【问题标题】:Using routes to generate URLs in a Symfony task在 Symfony 任务中使用路由生成 URL
【发布时间】:2010-07-19 23:37:10
【问题描述】:

我在 Ubuntu 10.0.4 LTS 上运行 Symfony 1.3.6。

我编写了一个 Symfony 任务,它生成一个包含链接(URL)的报告。

这是我的任务类中 execute() 方法的 sn-p:

  protected function execute($arguments = array(), $options = array())
  {
    //create a context
    sfContext::createInstance($this->configuration);
    sfContext::getInstance()->getConfiguration()->loadHelpers(array('Url', 'Asset', 'Tag'));

    ...
    $url = url_for("@foobar?cow=marymoo&id=42");

    // Line 1
    echo '<a href="'.$url.'">This is a test</a>';

    // Line 2
    echo link_to('This is a test', $url); 
  }

路由名称是这样定义的:

foobar:
  url: /some/fancy/path/:cow/:id/hello.html
  param: {  module: mymodule, action: myaction }

运行时,生成的链接是:

第 1 行 产生以下输出:

./symfony/symfony/some/fancy/path/marymoo/42/hello.html

而不是预期的:

/some/fancy/path/marymoo/42/hello.html

第 2 行生成错误:

找不到匹配的路由到 为参数“数组( '动作' => 'symfony', '模块' => '.',)"。

同样,预期的 URL 是:

/some/fancy/path/marymoo/42/hello.html

我该如何解决这个问题?

【问题讨论】:

    标签: symfony1 symfony-1.4


    【解决方案1】:

    在任务中生成 URL:

    protected function execute($arguments = array(), $options = array())
    {
      $routing = $this->getRouting();
      $url = $routing->generate('route_name', $parameters);
    }
    

    我们添加一个方法来生成路由,以便始终使用生产 URL:

       /**
       * Gets routing with the host url set to the url of the production server
       * @return sfPatternRouting
       */
      protected function getProductionRouting()
      {
        $routing = $this->getRouting();
        $routingOptions = $routing->getOptions();
        $routingOptions['context']['host'] = 'www.example.com';
        $routing->initialize($this->dispatcher, $routing->getCache(), $routingOptions);
        return $routing;
      }
    

    【讨论】:

    • +1 表示简洁明了的 sn-p,它向我展示了如何解决这个问题。我将稍微修改代码以适应我正在做的事情,测试它,如果它有效,我会接受这个答案。
    • 我应该把这个sn-p放在哪里?我不能从任务中调用 $this->getRouting() :/
    • 您可以在任务中使用 sfContext::getInstance()->getRouting()。
    【解决方案2】:

    我想使用标准助手(如 url_for)来生成 url,也许这段代码可以帮助你:

      protected function execute($arguments = array(), $options = array())
      {
        // initialize the database connection
    ...
    $context = sfContext::createInstance($this->configuration);
    
    $routing = $context->getRouting();
    $_options = $routing->getOptions();
    $_options['context']['prefix'] = "";// "/frontend_dev.php" for dev; or "" for prod
    $_options['context']['host'] = sfConfig::get('app_url_base');
    $routing->initialize($this->dispatcher, $routing->getCache(),$_options);
    $context->getConfiguration()->loadHelpers('Partial');
    $context->set('routing',$routing);    
    //$_SERVER['HTTP_HOST'] = sfConfig::get('app_url_base'); // ---> I don't remember why I have this on my code, shouldn't be necessary
    ...
    

    然后,您可以使用带有 absolute=true 参数的 url_for 函数 everywhere 神奇地工作。

    当然,您需要在 app.yml 中添加一个 *url_base* 定义(或者您可以将其保留为硬编码)

    【讨论】:

    • 非常感谢,这对我有用。小评论:$options 用于任务命令行选项,因此变量的不同名称可以避免问题..
    【解决方案3】:

    我也遇到了同样的问题,发现以下代码片段:http://snippets.symfony-project.org/snippet/378

    解决方案非常相似,但是它扩展了 ProjectConfiguration。这种方法的优点是,它也可以在模块中透明地工作。

    【讨论】:

      【解决方案4】:

      您可以在项目配置脚本config/ProjectConfiguration.class.php中调整命令(sfTask)的默认请求选项

      class ProjectConfiguration extends sfProjectConfiguration {
      
          public function setup() {
              ...
              $this->dispatcher->connect('command.pre_command', array('TaskWebRequest', 'patchConfig'));
          }
      
      }
      
      class TaskWebRequest extends sfWebRequest {
      
          public function __construct(sfEventDispatcher $dispatcher, $parameters = array(), $attributes = array(), $options = array())
          {
              $options['no_script_name'] = true;
              $options['relative_url_root'] = '';
              parent::__construct($dispatcher, $parameters, $attributes, $options);
          }
      
          public static function patchConfig(sfEvent $event) {
              sfConfig::set('sf_factory_request', 'TaskWebRequest');
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-07
        • 1970-01-01
        • 2019-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多