将 url 查询参数与控制器一起使用
Using the url query parameter with a controller
我正在尝试使用 Silverstripe 框架实现 oembed 提供程序,但遇到了一个问题。
我有一个从 url /omebed.json 路由的控制器,如果我调用类似 /omebed.json?mediaurl=mymovie.mp4 的东西,它工作正常。
但是 Oembed 标准声明它应该是 /omebed.json?url=mymovie.mp4
但是 Silverstripe 会在内部检查 $_GET['url'] 变量并将尝试路由到那个 page/controller。
所以 SilverStripe 正在尝试路由到 /mymovie.mp4 跳过我的控制器并点击 ErrorPage_Controller 创建 404.
我认为如果 url 是 oembed.json,我将不得不扩展 ErrorPage_Controller 并重新调整它,但这似乎有点老套。
有什么建议吗?
干杯
前几天我快速玩了一下。看看 main.php
做了什么 可能 最好破解它而不是 ErrorPage_controller
。
对于启动 SS 的默认 .htaccess
文件执行此操作:
<IfModule mod_rewrite.c>
SetEnv HTTP_MOD_REWRITE On
RewriteEngine On
# RewriteBase /silverstripe
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* framework/main.php?url=%1&%{QUERY_STRING} [L]
</IfModule>
请注意 ?url
将其更改为其他内容然后更改 main.php
的用法以及 may/should 帮助或将导致大量额外的错误和悲伤。
为避免破解 core/framework,您可以更改 .htaccess 以将 mysite
中的 main.php 的副本作为目标(适当包含更改)。
扩展@Stephen 的回答,这里有一种解决该问题的方法,无需复制 main.php
且无需直接修改它。
我所做的是创建一个 _ss_environment.php
file,它是在 Silverstripe 加载过程的早期添加的。
_ss_environment.php
global $url;
$url = $_GET['raw_url'];
if (isset($_GET['url']))
{
unset($_GET['url']);
}
// IIS includes get variables in url
$i = strpos($url, '?');
if($i !== false)
{
$url = substr($url, 0, $i);
}
.htaccess
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\.php$
RewriteRule .* framework/main.php?raw_url=%1 [QSA]
所以这是正在发生的事情:
.htaccess
现在使用 raw_url
而不是 url
_ss_environment.php
在加载过程的早期被调用,设置 global $url
variable that main.php
normally sets。这是用 raw_url
而不是 url
设置的。
- 为了防止
main.php
在看到您的 url
查询字符串参数时再次覆盖它,它未设置(就我的测试而言,Silverstripe 似乎稍后会重置它)。
- 最后是
main.php
would normally run if $_GET['url']
is set 的一小段代码,按原样复制以在 IIS 中提供明显的支持。 (如果您不使用 IIS,您可能不需要它。)
这有几个好处:
- 没有对
main.php
的更新允许将来更容易升级 Silverstripe
- 运行 "trick" Silverstripe 正常认为它是 运行 所需的最少量代码。
任何改变 url
查询字符串参数的解决方案的一个明显缺点是直接查看参数。根据 Silverstripe 的工作方式,代码更有可能使用 $url
全局变量或 Director
class 而不是查看当前 URL.
的查询字符串
我在 3.1 站点上进行了我提到的更改并进行了测试:
- 正在创建一个名为
TestController
的控制器
在controller的init
函数中,我是运行以下的:
var_dump($_GET['url']);
var_dump($this->getRequest()->getVars());
- 访问了
/TestController?url=abc123
,看到两个转储的值都有 "abc123" 作为 URL 参数的值。
- 导航到网站上的其他几个自定义页面以确保它们仍在工作(我没有看到任何问题)
遗憾的是,我无法找到有关 _config.php
和 _ss_environment.php
的包含顺序的文档。但是,在浏览代码后,我发现它是这样的:
main.php
runs, first main task is to require core/Constants.php
Constants.php
's first task is to search for _ss_environment.php
in the base folder and potential parent folders.找到就收录
- 回到
main.php
(并且在$_GET['url']
检查完成后main.php
),它会开始一个ErrorControlChain
其中 it internally does another require for core/Core.php
- Inside
Core.php
, it performs calls for the config manifest
ConfigManifest.php
exposes the functions to actually add _config.php
files and for them to be required.
我可能会继续,但我认为这很好地描述了正在发生的事情。我真的没有看到不使用 _ss_environment.php
文件的方法。没有其他任何内容都包含得足够早,您可以在不修改核心代码的情况下挂钩。
我正在尝试使用 Silverstripe 框架实现 oembed 提供程序,但遇到了一个问题。
我有一个从 url /omebed.json 路由的控制器,如果我调用类似 /omebed.json?mediaurl=mymovie.mp4 的东西,它工作正常。
但是 Oembed 标准声明它应该是 /omebed.json?url=mymovie.mp4
但是 Silverstripe 会在内部检查 $_GET['url'] 变量并将尝试路由到那个 page/controller。 所以 SilverStripe 正在尝试路由到 /mymovie.mp4 跳过我的控制器并点击 ErrorPage_Controller 创建 404.
我认为如果 url 是 oembed.json,我将不得不扩展 ErrorPage_Controller 并重新调整它,但这似乎有点老套。
有什么建议吗?
干杯
前几天我快速玩了一下。看看 main.php
做了什么 可能 最好破解它而不是 ErrorPage_controller
。
对于启动 SS 的默认 .htaccess
文件执行此操作:
<IfModule mod_rewrite.c>
SetEnv HTTP_MOD_REWRITE On
RewriteEngine On
# RewriteBase /silverstripe
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* framework/main.php?url=%1&%{QUERY_STRING} [L]
</IfModule>
请注意 ?url
将其更改为其他内容然后更改 main.php
的用法以及 may/should 帮助或将导致大量额外的错误和悲伤。
为避免破解 core/framework,您可以更改 .htaccess 以将 mysite
中的 main.php 的副本作为目标(适当包含更改)。
扩展@Stephen 的回答,这里有一种解决该问题的方法,无需复制 main.php
且无需直接修改它。
我所做的是创建一个 _ss_environment.php
file,它是在 Silverstripe 加载过程的早期添加的。
_ss_environment.php
global $url;
$url = $_GET['raw_url'];
if (isset($_GET['url']))
{
unset($_GET['url']);
}
// IIS includes get variables in url
$i = strpos($url, '?');
if($i !== false)
{
$url = substr($url, 0, $i);
}
.htaccess
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\.php$
RewriteRule .* framework/main.php?raw_url=%1 [QSA]
所以这是正在发生的事情:
.htaccess
现在使用raw_url
而不是url
_ss_environment.php
在加载过程的早期被调用,设置 global$url
variable thatmain.php
normally sets。这是用raw_url
而不是url
设置的。- 为了防止
main.php
在看到您的url
查询字符串参数时再次覆盖它,它未设置(就我的测试而言,Silverstripe 似乎稍后会重置它)。 - 最后是
main.php
would normally run if$_GET['url']
is set 的一小段代码,按原样复制以在 IIS 中提供明显的支持。 (如果您不使用 IIS,您可能不需要它。)
这有几个好处:
- 没有对
main.php
的更新允许将来更容易升级 Silverstripe - 运行 "trick" Silverstripe 正常认为它是 运行 所需的最少量代码。
任何改变 url
查询字符串参数的解决方案的一个明显缺点是直接查看参数。根据 Silverstripe 的工作方式,代码更有可能使用 $url
全局变量或 Director
class 而不是查看当前 URL.
我在 3.1 站点上进行了我提到的更改并进行了测试:
- 正在创建一个名为
TestController
的控制器
在controller的
init
函数中,我是运行以下的:var_dump($_GET['url']); var_dump($this->getRequest()->getVars());
- 访问了
/TestController?url=abc123
,看到两个转储的值都有 "abc123" 作为 URL 参数的值。 - 导航到网站上的其他几个自定义页面以确保它们仍在工作(我没有看到任何问题)
遗憾的是,我无法找到有关 _config.php
和 _ss_environment.php
的包含顺序的文档。但是,在浏览代码后,我发现它是这样的:
main.php
runs, first main task is to requirecore/Constants.php
Constants.php
's first task is to search for_ss_environment.php
in the base folder and potential parent folders.找到就收录- 回到
main.php
(并且在$_GET['url']
检查完成后main.php
),它会开始一个ErrorControlChain
其中 it internally does another require forcore/Core.php
- Inside
Core.php
, it performs calls for the config manifest ConfigManifest.php
exposes the functions to actually add_config.php
files and for them to be required.
我可能会继续,但我认为这很好地描述了正在发生的事情。我真的没有看到不使用 _ss_environment.php
文件的方法。没有其他任何内容都包含得足够早,您可以在不修改核心代码的情况下挂钩。