【问题标题】:Problem with URL encoded parameters in URL view helperURL 视图助手中的 URL 编码参数问题
【发布时间】:2011-04-06 11:41:48
【问题描述】:

所以我的问题有点奇怪,它只发生在我离线测试应用程序时(在我的带有 WampServer 的 PC 上),相同的代码在线工作 100% 正确。

这是我如何使用帮助器(只是示例):

<a href="<?php

echo $this->url(array('module' => 'admin',
                      'controller' => 'index',
                      'action' => 'approve-photo',
                      'id' => $this->escape($a->id),
                      'ret' => urlencode('admin/index/photos')),
                null,
                true);

                            ?>" class="blue">approve</a>

在线,这个链接很好用,它的动作类似于:

public function approvePhotoAction()
{
    $request = $this->getRequest();
    $photos = $this->_getTable('Photos');

    $dbTrans = false;

    try {

        $db = $this->_getDb();
        $dbTrans = $db->beginTransaction();

        $photos->edit($request->getParam('id'),
                      array('status' => 'approved'));

        $db->commit();

    } catch (Exception $e) {
        if (true === $dbTrans) {
            $db->rollBack();
        }
    }

    $this->_redirect(urldecode($request->getParam('ret')));
}

所以在线,它会批准照片并重定向回在 URL 中编码为“ret”参数的 URL(“admin/index/photos”)。

但使用 WampServer 离线时,我单击链接并收到如下 404 错误:

Not Found

The requested URL /public/admin/index/approve-photo/id/1/ret/admin/index/photos was not found on this server.

什么鬼?

我正在使用最新版本的 WampServer (WampServer 2.0i [11/07/09])。其他一切正常。

这是我的 .htaccess 文件,以防万一:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]

# Turn off magic quotes
#php_flag magic_quotes_gpc off

我正在使用虚拟主机在本地 PC 上测试 ZF 项目。这是我添加虚拟主机的方法。

httpd.conf:

NameVirtualHost *:80
<VirtualHost *:80>
    ServerName myproject
    DocumentRoot "C:\wamp\www\myproject"
</VirtualHost>

主机文件:

127.0.0.1    myproject

任何帮助都将不胜感激,因为这使得在我的本地主机上测试和调试项目成为一场噩梦,几乎不可能完成任务。我必须在线上传所有内容以检查它是否有效:(

更新:

_redirect 助手的源代码(内置 ZF 助手):

/**
 * Set redirect in response object
 *
 * @return void
 */
protected function _redirect($url)
{
    if ($this->getUseAbsoluteUri() && !preg_match('#^(https?|ftp)://#', $url)) {
        $host  = (isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:'');
        $proto = (isset($_SERVER['HTTPS'])&&$_SERVER['HTTPS']!=="off") ? 'https' : 'http';
        $port  = (isset($_SERVER['SERVER_PORT'])?$_SERVER['SERVER_PORT']:80);
        $uri   = $proto . '://' . $host;
        if ((('http' == $proto) && (80 != $port)) || (('https' == $proto) && (443 != $port))) {
            $uri .= ':' . $port;
        }
        $url = $uri . '/' . ltrim($url, '/');
    }
    $this->_redirectUrl = $url;
    $this->getResponse()->setRedirect($url, $this->getCode());
}

更新 2:

离线助手的输出:

/admin/index/approve-photo/id/1/ret/admin%252Findex%252Fphotos

和在线(一样):

/admin/index/approve-photo/id/1/ret/admin%252Findex%252Fphotos

更新 3:

好的。问题实际上出在虚拟主机配置上。文档根目录设置为 C:\wamp\www\myproject 而不是 C:\wamp\www\myproject\public。

我正在使用这个 htaccess 重定向到公用文件夹:

RewriteEngine On

php_value upload_max_filesize 15M
php_value post_max_size 15M
php_value max_execution_time 200
php_value max_input_time 200
# Exclude some directories from URI rewriting
#RewriteRule ^(dir1|dir2|dir3) - [L]

RewriteRule ^\.htaccess$ - [F]

RewriteCond %{REQUEST_URI} =""
RewriteRule ^.*$ /public/index.php [NC,L]

RewriteCond %{REQUEST_URI} !^/public/.*$
RewriteRule ^(.*)$ /public/$1

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [NC,L]

RewriteRule ^public/.*$ /public/index.php [NC,L]

该死的我不知道为什么我忘记了这个,我以为虚拟主机配置正确到公用文件夹,我 100% 确定这一点,我也仔细检查了一下,发现没有问题(wtf?am我瞎了?)。

【问题讨论】:

  • 你能贴出 $this->redirect 的代码吗?
  • $this->_redirect 是 Zend 框架中的内置助手,但我在帖子中包含了来自 ZF 的源代码。
  • 看看我的default%2Fstatic%2Ffaq和你的/admin%252Findex%252Fphotos你的网址被编码了两次
  • 是的,但它仍然有效。我现在没有时间从所有视图中删除 urlencode。这需要几个小时,所以我就这样离开它,以防它在未来再次停止工作,我将只使用 urldecode 两次 :)
  • 您可以编写 ActionHelper 来检查 ret 参数是否存在 - 对其进行 urldecode ;) 并在 ActionControllers 中编写并继续编写正确的代码。无需加倍 urldecode ;)

标签: php zend-framework


【解决方案1】:
  1. 检查您的 php.ini
    php_flag magic_quotes_gpc off 在线和本地服务器上必须是 Off

  2. 不要使用urlencode'ret' =&gt; urlencode('admin/index/photos')),因为url助手有第四个参数$encode = true,默认是true

  3. 向我们展示$this-&gt;url(array('module' =&gt; 'admin'..... 在服务器和本地主机上的输出

我在家里使用 wamp,它就像魅力一样工作

更新 1
试试$this-&gt;_redirect( '/'. ltrim(urldecode($request-&gt;getParam('ret')), '/') );

更新 2;

视图脚本

    <a href="<?php

echo $this->url(array('module' => 'default',
                  'controller' => 'index',
                  'action' => 'test-encoded-redirect',
                  'ret' => urlencode('default/static/faq')),
            null,
            true);

                        ?>">test me</a>


    <?php
    class IndexController extends Smapp_Controller_Action 
    {   

        public function testEncodedRedirectAction()
        {

                            // ddump($this->_getAllParams());
            // ddump output 
            // Array ( 
            //  [controller] => index 
            //  [action] => test-encoded-redirect 
            //  [ret] => default%2Fstatic%2Ffaq 
            //  [module] => default 
            // )


            $ret = '/' . ltrim(urldecode($this->_getParam('ret')), '/');
            // echo $ret;
            // output: /default/static/faq

            $this->_redirect($ret);
        }
    }

有效!

【讨论】:

  • 魔术引号在本地和 Web 服务器上均已关闭。检查我的帖子的结尾。
  • 而 urlencode() 不是问题。如果我摆脱它,问题仍然存在。另外,它是一个较旧的应用程序,我必须在几十个视图中删除该 urlencode()(在较旧的 ZF 版本中,我认为第四个参数不存在,因此他们确保旧的 ZF 应用程序不会损坏)。
  • :) 好的。显示echo ltrim(urldecode($request-&gt;getParam('ret')), '/') 输出
  • 可能是baseUrl的问题。因为最终链接在本地主机上看起来像/public/ret/admin/index/photos,在服务器上看起来像/admin/index/photos
  • 如果是这样 - 你必须重新配置你的 WAMP VirtualHost 指向 'DocumentRoot "C:\wamp\www\myproject\public"`
猜你喜欢
  • 1970-01-01
  • 2011-06-08
  • 2011-04-21
  • 2016-08-14
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
  • 2020-09-20
  • 1970-01-01
相关资源
最近更新 更多