【发布时间】:2013-09-08 10:11:34
【问题描述】:
这与我之前问过的一个问题有关:Replacing named 'parameters' within a string in PHP
那个小类过去可以工作,但现在我正试图将它作为扩展移至新的 Bolt CMS。
目的是从 YML 文件中获取数据。数据如下:
redirects:
contentToPage:
from: "content/(slug:any)"
to: "page/{slug}"
扩展程序循环遍历此数据并将其与当前请求 URI 进行比较,该请求 URI 是从适用的 Symfony 组件获得的。如果匹配,用户将被相应地重定向。因此,在这种情况下,如果用户尝试访问content/test,他们将被重定向到page/test。
但似乎出了点问题,转换后的替换不正确,或者我得到了一个错误。首先,这是有问题的块:
$convertedReplacements = preg_replace_callback("/^{$convertedPlaceholders}$/", function ($captures) {
$result = $this->destination;
for ($c = 1, $n = count($captures); $c < $n; ++$c) {
$value = array_shift($this->computedReplacements);
$result = str_replace("\{$value\}", $captures[$c], $result);
}
return $result;
}, $requestUri);
$convertedPlaceholders 包含 from 值中的替换参数。因此,(slug:any) 将被替换为 ([a-z0-9\.\-\_\%\=]+)。现在,这可行,但该函数会引发此异常:preg_replace_callback(): Unknown modifier '('。
但是,如果我将正则表达式分隔符从 / 更改为 ~ 或 #,我不会收到错误消息。相反,我在 YML 文件中获取了 to 属性的值。在这种情况下,我得到page/{slug} 而不是page/test。
我一定在做一些愚蠢的事情,我不知道那是什么。据我所知,我只是遗漏了一些我看不到的东西。
这是整个扩展:
<?php
// Redirector Extension for Bolt
// Minimum version: 1.2
namespace Redirector;
use Silex\Application as Application;
use Symfony\Component\HttpFoundation\Request as Request;
use Symfony\Component\Yaml\Parser as Parser;
use Bolt\BaseExtension as BoltExtension;
class Extension extends BoltExtension
{
protected $placeholders = array(
':all' => '.*',
':alpha' => '[a-z]+',
':alphanum' => '[a-z0-9]+',
':any' => '[a-z0-9\.\-\_\%\=]+',
':num' => '[0-9]+',
':segment' => '[a-z0-9\-\_]+',
':segments' => '[a-z0-9\-\_\/]+'
);
protected $computedReplacements;
protected $destination;
/**
* Basic information about the extension. Shown in the Bolt Admin Environment.
*
* @return Array
*/
function info() {
$data = array(
'name' => 'Redirector',
'version' => '0.1',
'author' => 'Foundry Code - Mike Anthony',
'description' => 'An extension that allows you to perform any pre-app <code>301 Moved Permanently</code> redirects.',
'type' => 'Pre-app Hook',
'link' => 'http://code.foundrybusiness.co.za/extensions/bolt-redirector',
'first_releasedate' => '2013-08-28',
'latest_releasedate' => '2013-08-28',
'required_bolt_version' => '1.2',
'highest_bolt_version' => '1.2'
);
return $data;
}
/**
* Initialise the extension's functions
*
* @return void
*/
function initialize() {
$this->options = $this->config['options'];
$this->redirects = $this->config['redirects'];
$this->handleRedirects();
}
/**
* Check for a redirect. If it exists, then redirect to it's computed replacement.
*
* @return ? Response
*/
function handleRedirects()
{
$redirector = $this;
$this->app->before(function (Request $request) use ($redirector) {
if (empty($redirector->redirects)) {
return;
}
$requestUri = trim($request->getRequestUri(), '/');
$availablePlaceholders = '';
foreach ($this->placeholders as $placeholder => $expression) {
$availablePlaceholders .= ltrim("$placeholder|", ':');
}
$availablePlaceholders = rtrim($availablePlaceholders, '|');
//die($availablePlaceholders);
$pattern = '/\{(\w+):('.$availablePlaceholders.')\}/';
//die($pattern);
foreach ($this->redirects as $redirectName => $redirectData) {
$this->computedReplacements = array();
$this->destination = $redirectData['to'];
$from = rtrim($redirectData['from'], '/');
$to = rtrim($redirectData['to'], '/');
$convertedPlaceholders = preg_replace_callback($pattern, function ($captures) {
$this->computedReplacements[] = $captures[1];
return '(' . $this->placeholders[":{$captures[2]}"] . ')';
}, $from);
//die($convertedPlaceholders);
$convertedReplacements = preg_replace_callback("/^{$convertedPlaceholders}$/", function ($captures) {
$result = $this->destination;
for ($c = 1, $n = count($captures); $c < $n; ++$c) {
$value = array_shift($this->computedReplacements);
$result = str_replace("\{$value\}", $captures[$c], $result);
}
return $result;
}, $requestUri);
die($convertedReplacements);
if (preg_match("~^{$convertedPlaceholders}$~i", $requestUri)) {
return $this->app->redirect("/$convertedReplacements", 301);
}
}
}, Application::EARLY_EVENT);
}
}
关于我可以在这里做什么的任何想法?
【问题讨论】:
标签: php regex arrays routing uri