感谢来自TheDeadMedic, 我知道我的问题是由我自己的应用程序环境引起的,我在问题中没有提供,因为我认为这与我的应用程序环境无关。Sorry about that! 我通常会在发帖时简要描述一下环境,但之前从未有过相关内容,所以这次我跳过了它:-(
我正在使用WordPress
作为Zend Framework MVC application
这需要登录。访问几乎所有WordPress
页面要求用户登录到ZF application
; 如果没有登录ZF session
当发出请求时,请求被重定向到登录页面,并且登录页面显示一条消息,说明需要登录-但该页面显示的状态代码为200(奇怪的是,我最近考虑过在显示带有该消息的登录页面时提供401或403状态的更改,但我还没有这样做)。
网络升级。php脚本使用cURL
请求升级。网络中每个子站点的php脚本。这些cURL请求实际上得到了一个响应(重定向后),该响应只是ZF application
; 但由于其状态代码为200,网络升级认为每个站点升级都成功了,每个人都很高兴,即使wp db中没有任何更改。
当我说根站点已升级时,我感到困惑/误解。我一定是手动更新了它,但忘记了在使用phpMyAdmin
查看数据库发生了什么。从备份开始,我可以看到,在运行网络升级时wp_*options
桌上有他们的db_version
更新(也没有wp_blog_versions
表得到更新)。
目前我可以手动更新每个子站点,因为只有10个,但这个数字应该会大幅增长。我想我会问一个新问题,看看有没有办法cURL
请求使用调用代码的PHP会话(ZF application
在会话中存储登录状态)。
The underlying problem and solution
如上所述
cURL
请求(发生在
WP_Http::request()
, 呼叫人
network/upgrade.php
要升级每个单独的子站点),请重定向到
ZF application\'s
登录页面。这是因为他们没有访问与网络升级脚本相同的PHP会话,因为他们没有通过
PHPSESSID
曲奇
cURL
和
WP_Http::request()
提供一种通过请求传递cookie的方法,并且有一个名为“http\\u request\\u args”的过滤器,可用于将cookie添加到请求中。我可以用它来通过
PHPSESSID
cookie改进了行为,但仍然不太正确。结果发现还有两个问题:
我要集成的代码WordPress
进入ZF application
阻止访问根站点,除非WordPress
用户是超级管理员。从那以后WordPress
使用cookie来维护登录状态,这些cookie还需要在运行升级脚本的请求中传递。显然,单个升级脚本本身没有检查WordPress
登录状态(!)。因此,我使用“http\\u request\\u args”过滤器在$_COOKIE
超全局。
当PHP会话处于活动状态时,保存会话数据的文件将被锁定。因此,为了让运行升级脚本的请求使用调用脚本的会话,调用脚本需要调用session_write_close()
解锁会话文件。WordPress本身没有问题,因为它不使用会话,但对于我与ZF application
. 我无法轻松找到添加该调用的挂钩,因此我将其编辑到核心class-http.php
调用之前的文件Requests::request
, 受我的ZF application
集成处于活动状态,PHP会话处于活动状态,并且正在向当前请求中指定的同一服务器发出请求:
if (ZF_PLUGGABLE_RUN && session_status() == PHP_SESSION_ACTIVE && $defaults[\'cookies\'] == $_COOKIE) {
// PHP keeps session file locked, need to close it to allow the request to use it
session_write_close();
}
我确实尽量避免编辑核心文件,但在很多地方,我都找不到合适的钩子。我将核心文件保存在
git
并分别跟踪我在每个版本中更改的每个文件,以便获取一个新版本需要一个非常小的定义良好的合并过程。
Final solution without editing core file
尽管在调用之前没有钩子
Requests::request()
, 事实证明,“http\\u request\\u args”过滤器足够接近。因此,现在我已经删除了核心文件编辑,只需定义“http\\u request\\u args”过滤器,如下所示(在定义其他集成过滤器的类中
WordPress
与我的
ZF application
). 我只在需要
ZF application
集成是主动的,所以我不需要测试
ZF_PLUGGABLE_RUN
常数:
public function http_request_args($args, $url) {
$retval = $args;
if (@parse_url($url, PHP_URL_HOST) == $_SERVER[\'SERVER_NAME\']) {
// The request is going to our own server, so we need to provide it our current cookies,
// including both PHPSESSID for the session holding the ZF user, and the WordPress cookies
// holding the WordPress user.
if (! array_key_exists(\'cookies\', $args)) {
// The default array settings in WP_Http::request() include a \'cookies\' element,
// so that element should always be present in $args.
throw new Exception("Unexpected: \\$args does not contain an element name \'cookies\'");
}
if (! is_array($args[\'cookies\'])) {
// The default value of $args[\'cookies\'] is an empty array, not null
throw new Exception("Unexpected: \\$args[\'cookies\'] is not an array");
}
// In known example of self-directed requests for database update, $args[\'cookies\']
// will be empty. But for generality, instead of assigning it a value, just merge in
// the $_COOKIE superglobal, letting any user-specified cookies in $args[\'cookies\'] override.
$retval[\'cookies\'] = array_merge($_COOKIE, $args[\'cookies\']);
// PHP keeps the session file locked, so we need to close it to allow the request to use it
if (session_status() == PHP_SESSION_ACTIVE) {
session_write_close();
}
}
return $retval;
}