【问题标题】:ZF2 Generate absolute URI from CLIZF2 从 CLI 生成绝对 URI
【发布时间】:2014-01-16 20:11:21
【问题描述】:

我有一个 cron 作业,它运行 ZF2 CLI 路由来发送一些电子邮件通知。电子邮件使用我通过呈现的 HTML 视图

$emailBody = $this->getServiceLocator()->get('viewrenderer')
               ->render('some/partial/name.phtml',$params);

在这部分我使用视图助手

<?php echo $this->url('some-route', array(), array('force_canonical' => true)); ?>

生成指向我网站上页面的绝对 URL。但是,当我通过 CLI 运行它时,我看到了一个异常:

Zend\Mvc\Router\Exception\RuntimeException
Request URI has not been set

我是否需要将虚拟 HttpRequest 对象注入到视图呈现服务中,还是应该以不同的方式处理?

【问题讨论】:

    标签: url zend-framework2 view-helpers


    【解决方案1】:

    因为这是通过 CLI 运行的,所以脚本无法知道正确的域来生成绝对 URI。

    我最终在 module/Application/src/Application/View/Helper/CliDomain.php

    创建了一个视图助手
    <?php
    namespace Application\View\Helper;
    use Zend\View\Helper\AbstractHelper;
    
    class CliDomain extends AbstractHelper {
        protected $_config_protocol;
    
        protected $_config_domain;
    
        public function __construct(array $cliConfig) {
            $this->_config_protocol = $cliConfig['scheme'];
            $this->_config_domain = $cliConfig['domain'];
        }
    
        public function __invoke() {
            return $this->_config_protocol.'://'.$this->_config_domain;
        }
    
    }
    

    并在module/Application/config/module.config.php

    中配置工厂
    return array(
        ...
        'view_helpers' => array(
            ...
            'cliDomain' => function ($sm) {
                    $config = $sm->getServiceLocator()->get('config');
                    if (!isset($config['cli_url'])) {
                        throw new \InvalidArgumentException('Please add a "cli_url" configuration to your project in order for cron tasks to generate emails with absolute URIs');
                    }
                    return new \Application\View\Helper\CliDomain($config['cli_url']);
                },
    

    在项目的 config/autoload/global.php 文件中,我向返回的数组添加了一个新键

    <?php
    return array(
        ...
        'cli_config' => array(
            'scheme' => 'http',
            'domain' => 'prod.example.com',
        ),
    );
    

    对于登台服务器,我在 config/autoload/local.php

    中添加了一个匹配的配置条目
    <?php
    return array(
        ...
        'cli_config' => array(
            'scheme' => 'http',
            'domain' => 'staging.example.com',
        ),
    );
    

    因此,在问题的视图脚本中,我只是在 URL 中添加了对帮助程序的调用,而不必费心强制规范。

    <a href="<?php echo $this->cliDomain() . $this->url('some-route'); ?>">a link!</a>
    

    【讨论】:

      【解决方案2】:

      一种方法是将Uri\Http 对象传递给url() 视图助手:

      <?php
      // at the top of your view script, or passed assigned to the view model
      $uri = new \Zend\Uri\Http('http://www.example.com/subdir');
      ?>
      
      
      <!-- within the view script -->
      <?= $this->url('some-route', array(),
          array('force_canonical' => true, 'uri' => $uri)); ?>
      

      或者只是在视图脚本中编码:

      http://example.com/subdir<?= $this->url('some-route'); ?>
      

      (我假设你使用的是 PHP5.4 或更高版本,所以你可以使用&lt;?=

      【讨论】:

      • 是的,但这否定了我试图做的事情:让代码生成一个指向正确环境的绝对 URL。我希望找到一种方法让 cron 作业在登台服务器上生成带有 staging.example.com 链接的电子邮件,在生产服务器上生成带有 prod.example.com 链接的电子邮件,而无需更改视图脚本的主机跨度>
      猜你喜欢
      • 2013-03-23
      • 2011-05-22
      • 2012-10-02
      • 1970-01-01
      • 2014-07-04
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      • 1970-01-01
      相关资源
      最近更新 更多