这与我之前问过的一个问题有关:Replacing named 'parameters' within a string in PHP
那个小类过去可以工作,但它似乎行为不端,现在我正试图将它移到新的 Bolt CMS 作为扩展。
目的是从 YML 文件中获取数据。数据如下所示:
redirects:
contentToPage:
from: "content/(slug:any)"
to: "page/{slug}"
扩展循环遍历这些数据并将其与从适用的 Symfony 组件获得的当前请求 URI 进行比较。如果匹配,用户将被相应地重定向。因此,在这种情况下,如果用户尝试访问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 '('
.
但是,如果我将正则表达式分隔符从/
to更改为~
or #
,我不会收到错误消息。相反,我得到了to
在 YML 文件中获取属性的值。在这种情况下,我得到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);
}
}
关于我可以在这里做什么的任何想法?