leaseweb/remote-template-bundle

此包已被废弃,不再维护。未建议替代包。

从远程站点加载(查看)模板

v1.0.1 2013-05-10 07:52 UTC

This package is not auto-updated.

Last update: 2020-10-30 19:10:14 UTC


README

此仓库不再积极维护。我们鼓励您不要使用此代码。如果您依赖此代码,您可能希望fork此仓库以防止系统崩溃,如果将来我们删除此仓库。

LswRemoteTemplateBundle

2011年12月21日,Stefan Koopmanschap在LeaseWeb Labs博客上撰写了一篇优秀的文章,题为“无痛苦(嗯,不那么痛苦)迁移到Symfony2”。在他的文章中,他解释了进行逐步迁移的优势。

查看:http://www.leaseweblabs.com/2011/12/painless-well-less-painful-migration-to-symfony2/

他提出的实现这一目标的技术解决方案是“...将您的旧应用程序包裹在您的Symfony2应用程序中。”他甚至还为我们提供了工具(The IngewikkeldWrapperBundle代码)来实现这一点。

查看:https://github.com/Ingewikkeld/IngewikkeldWrapperBundle

我们非常受他充满热情的阐述的启发,并且我们完全相信有必要尽快开始迁移到Symfony2。然而,他也为我们提供了一些“警告”:性能和身份验证/授权。这可能会让一些人担心,但不是我们:这挑战我们找到解决这两个开放问题的解决方案。

  1. 性能

正如Stefan Koopmanschap所解释的,在他的解决方案中,你“...使用两个框架处理所有旧页面”和“...两个框架比一个多出更多开销。”这让我们有些担心。失去性能并不是一个可行的选择,因此我们必须找到解决方案。

Symfony 1 & 2都使用Front Controller架构(一个文件处理所有请求),我们只是在寻找将流量分离到两个前控制器之间。Stefan提出了使用Symfony 2路由并使其使用回退路由来处理您的旧URL的方法。我们这里建议使用.htaccess重写。这几乎没有开销,因为每个Symfony请求都会由mod_rewrite重写。

  1. 身份验证/授权

他还写道:“另一个问题是会话。”进一步阐述问题,他表示:“如果您的应用程序需要身份验证和授权,您现在将不得不与两个不同的系统一起工作,这些系统对身份验证和授权有不同的处理方法。”由于我们的应用程序需要身份验证和授权,我们必须在这里想出解决方案。我们决定将身份验证(登录页面)移至Symfony2,并让Symfony1“信任”由“Symfony2”执行的身份验证。

为了实现此解决方案,我们必须使Symfony1能够“看到”和“理解”Symfony2会话。首先,我们确保两个应用程序使用相同的名称,通过在“app/config/config.yml”中将Symfony2“framework_session_name”设置设置为“symfony”。然后,我们逆向工程Symfony2会话存储,发现它将一些PHP对象序列化到其中。为了能够反序列化这些对象,我们必须在Symfony1中使用“spl_autoload_register”注册一个自动加载函数

最后,说明

为了解决性能问题,我们在Symfony1项目中的“sf2”目录(在“apps”旁边)安装了Symfony2,并首先更改“web/.htaccess”文件中的行

# redirect to front controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]

然后,在上面添加这些行

# redirect to new symfony2 front controller
RewriteCond %{REQUEST_FILENAME} !-f
# but only if URL matches one from this list:
RewriteCond %{REQUEST_URI} ^/users/login
# end of list
RewriteRule ^(.*)$ sf2/web/$1 [QSA,L]

为了支持在Symfony1中实现Symfony2的认证和授权,我们创建了一个名为“Symfony2AuthenticationFilter”的类。这个过滤器可以通过将其放在您的Symfony1项目的“lib/filter”文件夹下,并在“apps/ssc/config/filters.yml”文件中添加以下行来加载:

symfony2AuthenticationFilter:
    class: Symfony2AuthenticationFilter

为了配置过滤器,我们在“/apps/ssc/config/app.yml”中添加了一些新的应用设置。

all:
    symfony2:
        paths: ['sf2/vendor/symfony/src', 'sf2/src', 'sf2/vendor/bundles', 'sf2/vendor/doctrine-common/lib']
        attribute: '_security_main'

此路径设置表示Symfony2位于Symfony1项目的“sf2”子目录中。该属性反映了Symfony2防火墙的名称。Symfony2AuthenticationFilter的代码如下:

function symfony2_autoload ($pClassName)
{
  $sf2Paths = sfConfig::get('app_symfony2_paths');

  foreach ($sf2Paths as $path)
  {
    $path = sfConfig::get('sf_root_dir') . DIRECTORY_SEPARATOR . $path;
    $file = $path . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR ,$pClassName ) . ".php";

    if (file_exists($file))
    {
      include($file);
      break;
    }
  }
}

spl_autoload_register("symfony2_autoload");

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Security\Core\Role\Role;

class Symfony2AuthenticationFilter extends sfFilter
{
  public function execute($filterChain)
  { // get session data
    $sessionData = null;
    $symfony2Attribute = sfConfig::get('app_symfony2_attribute');
    if (isset($_SESSION['_symfony2']['attributes'][$symfony2Attribute]))
    { $sessionData = unserialize($_SESSION['_symfony2']['attributes'][$symfony2Attribute]);
    }
    // get sf1 username
    if (!$this->getContext()->getUser()->isAuthenticated()) $sf1UserName = false;
    else $sf1UserName = $this->getContext()->getUser()->getUserName();
    // get sf2 username
    if (!$sessionData) $sf2UserName = false;
    else $sf2UserName = $sessionData->getUser()->getUserName();
    // if usernames do not match
    if ($sf1UserName!=$sf2UserName)
    { if ($sf2UserName) // if symfony2 is signed in
      { // signin to symfony1
        $this->getContext()->getUser()->setUserName($sf2UserName);
        $this->getContext()->getUser()->setAuthenticated(true);
        $this->getContext()->getUser()->clearCredentials();
      }
      else // if symfony2 is not signed in
      { // signout from symfony1
        $this->getContext()->getUser()->setUserName(false);
        $this->getContext()->getUser()->setAuthenticated(false);
        $this->getContext()->getUser()->clearCredentials();
        // redirect to current page
        $path = $this->getContext()->getRequest()->getPathInfo();
        $this->getContext()->getController()->redirect($path);
      }
    }
    // and execute next filter
    $filterChain->execute();
  }
}
  1. 包安装

安装过程分为以下步骤:

  1. 使用composer下载LswRemoteTemplateBundle
  2. 启用Bundle
  3. 确保PHP中的cURL模块已启用

步骤1:使用composer下载LswRemoteTemplateBundle

在您的composer.json中添加LswRemoteTemplateBundle

{
    "require": {
        "leaseweb/remote-template-bundle": "*",
        ...
    }
}

现在运行以下命令告诉composer下载Bundle

$ php composer.phar update leaseweb/remote-template-bundle

composer会将Bundle安装到您项目的vendor/leaseweb目录。

步骤2:启用Bundle

在kernel中启用Bundle

<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new Lsw\RemoteTemplateBundle\LswRemoteTemplateBundle(),
    );
}

步骤3:确保PHP中的cURL模块已启用

在基于Debian的发行版(如Ubuntu)中,该软件包名为"php5-curl",可以使用以下命令安装:

$ sudo apt-get install php5-curl
$ sudo service apache2 restart

在基于RedHat的发行版(如CentOS)中,该软件包名为"php-curl",可以使用以下命令安装:

$ sudo yum install php-curl
$ sudo service httpd restart

为了检查此设置,创建并运行一个包含以下内容的PHP文件:

<?php phpinfo() ?>

它应该显示“cURL支持”选项设置为“已启用”。

如果PHP中启用了CURL支持,该软件包也应该在Windows安装上工作。