2009-10-22

Cheat Sheets!

类归于: PHP, symfony — 标签:, , maker @ 16:59

bobhero就喜欢搞一些稀奇古怪的东西,800块的古董式键盘买了两个外加一个超级怪异的轨迹球鼠标,智能手机买了两个一个打电话一个玩日历,Arch Linux装了Awesome然后接了两个显示器。早在两年之前,我刚来公司的时候,就对他的这些卡片很感兴趣。

cheatsheets

这个东西的英文名叫cheat sheet,找了很久也没有找到一个合适的中文名,不过我觉得叫备忘卡很合适。从以往的工作上来看,cheatsheet的确帮了不少忙,最关键是省了翻手册的时间,网上有很多的cheat sheet,打印下来,塑封,然后放在电脑旁,下面是来自Added Bytes的cheat sheets。

PHP  (V1) PHP (V2) Mysql
php-cheat-sheet-v1 php-cheat-sheet-v2 mysql-cheat-sheet-v1
JavaScript CSS (V1) CSS  (V2)
javascript-cheat-sheet-v1 css-cheat-sheet-v1 css-cheat-sheet-v2
mod_rewrite  (V1) mod_rewrite (V2) HTML
mod_rewrite-cheat-sheet-v1 mod_rewrite-cheat-sheet-v2 html-cheat-sheet-v1
正则表达式 (V1) 正则表达式 (V2) ASP/VBScript
regular-expressions-cheat-sheet-v1 regular-expressions-cheat-sheet-v2 asp-cheat-sheet-v1
Python (V1) Ruby on Rails Subversion(SVN)
python-cheat-sheet-v1 ruby-on-rails-cheat-sheet-v1 subversion-cheat-sheet-v1

请访问 http://www.addedbytes.com/cheat-sheets/获取更多的CheatSheets.

注意:打印cheatsheet最好打印pdf版本的,图片格式的清晰度可能不是很好。忘了提醒大家了,塑封的时候可以把两张塑封到一起,比如PHP(V1)和PHP(V2)可以塑封个反正面。

下面这些是symfony官方提供的cheat sheets,貌似是1.0的,不过或多或少还有些用处。

Symfony Admin Generator Symfony Directory Structure And CLI
symfony-admin-generator symfony-directory-structure-and-cli

请访问http://trac.symfony-project.org/wiki/CheatSheets来获取更多的symfony cheat sheets。下载链接我这里访问不了,不知道是删掉了还是被墙了,有新的发现我会再发出来。

http://www.addedbytes.com/cheat-sheets/php-cheat-sheet/

2009-08-01

成为一名symfony文档贡献者.

类归于: symfonymaker @ 00:32

很久没有更新博客了,最新的一些工作没有涉及到symfony相关的研究,不过利用了一些空闲参与了symfony文档的翻译工作。

其实目前来讲也不是真正的翻译,只是将网络上已经有的文档整理到symfony官方的svn中去,也算为symfony和广大国内的PHP开发者做一点点贡献。

在这也可以提醒一些symfony爱好者,官方的jobeet文档中文版又开始更新了,是整理自symfony中文的,目前还没有全部整理完,整理完毕之后我还会尝试完成friend没有发表出来的后几章的内容。

闲话不多讲了,现在主要说说如何参与到symfony的开发中去。

symfony项目是基于svn(subversion)的,所以如果你要参与到开发中去,一定要有一个svn账号,这个账号不是随便可以申请得到的,需要向symfony的管理者fabien(fabien.potencier[at]symfony-project.com)索取,不过貌似是不能参与symfony源码开发的(这个是我推测,如果你有能力也可以尝试和fabien协商一下)。

fabien貌似很忙,大概一周左右查收一次邮件,不过应该是有求必应的。在没有得到svn账号之前,你也是可以检出(checkout)symfony项目的。1.2相关文档的svn地址是:

http://svn.symfony-project.com/doc/branches/1.2

检出之后你就可以看到全部symfony1.2相关文档所有语言版本的源文件了,当然这不是最终体现在网页上的文档,发布到网页上还需要一个编译的过程。

svn

你也可以在symfony项目的trac(http://trac.symfony-project.org/browser)上查看全部源码。

如果你拥有了一个有修改权限的svn账号,你就可以开始你的翻译工作了,翻译完毕可以进行commit操作,commit之后是不会立刻体现在网页上的,上面说过,在那之前需要有一个编译的过程,一般是一天一次,多数在每天下午,可能不只是编译,fabien也会进行一些审核工作。

如果您的修改通过审核那么恭喜你,你成为了伟大的symfony的一名贡献者!

如果你不会操作svn或者没有得到svn账号,也可以将您的译文发给我(makerwang[at]gmail.com),我会帮你整理提交到官方的svn中去,关于版权的问题嘛,为了尊重原著,官方的翻译工作应该是匿名的,不过你仍然可以将您的翻译发布到其他地方,前提是你要遵守symfony的by-cc协议。

2009-06-20

判断搜索引擎爬虫

类归于: PHP — 标签:hansir85 @ 14:34

如何判断访问是否来自搜索引擎。
可以通过HTTP header 内的 HTTP USER AGENT 识别。
(还有别的方法)
Baiduspider+(+http://www.baidu.com/search/spider.htm)
这是百度的爬虫。

使用php变量,$_SERVER['HTTP_USER_AGENT']
以PHP程序为例:

$userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
$spiders = array('Baiduspider', 'Googlebot');//添加需要的爬虫关键字
foreach ($spiders as $spider)
{
$spider = strtolower($spider);
if (strpos($userAgent, $spider) !== false)
{
return 'is spider';
}
return 'is not spider';
}
?>

一些常用的爬虫
百度爬虫
Baiduspider+(+http://www.baidu.com/search/spider.htm)

雅虎爬虫,分别是雅虎中国和美国总部的爬虫
Mozilla/5.0 (compatible; Yahoo! Slurp China; http://misc.yahoo.com.cn/help.html)
Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)

新浪爱问爬虫
iaskspider/2.0(+http://iask.com/help/help_index.html)
Mozilla/5.0 (compatible; iaskspider/1.0; MSIE 6.0)

搜狗爬虫
Sogou web spider/3.0(+http://www.sogou.com/docs/help/webmasters.htm#07″)
Sogou Push Spider/3.0(+http://www.sogou.com/docs/help/webmasters.htm#07″)
【早期用法:“sogou spider”】

Google爬虫
Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

Google AdSense广告内容匹配爬虫
Mediapartners-Google/2.1

网易爬虫
Mozilla/5.0 (compatible; YodaoBot/1.0; http://www.yodao.com/help/webmaster/spider/;)
【早期采用“ OutfoxBot/0.5 (for internet experiments; http://”; outfoxbot@gmail.com)”】

Alexa排名爬虫
ia_archiver

MSN爬虫
msnbot/1.0 (+http://search.msn.com/msnbot.htm)
特点未知
msnbot-media/1.0 (+http://search.msn.com/msnbot.htm)

据称为北大天网的搜索引擎爬虫程序
P.Arthur 1.1

看来是Qihoo的
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; QihooBot 1.0)

Gigabot搜索引擎爬虫
Gigabot/2.0 (http://www.gigablast.com/spider.html)

来源 互联网 参考如何识别搜索引擎爬虫

2009-06-18

内嵌表单详解(How to Embed Forms in Symfony 1.2 Admin Generator 中文版)

类归于: symfony — 标签:, , maker @ 23:31

译者:Maker.Wang[at]gmail.com
原文:http://sandbox-ws.com/how-to-embed-forms-in-symfony-12-admin-generator

译者注: Embed form是一个被忽略了的却很实用的技术,可能是由于embed form是新功能的缘故,相关的文档非常少,特别是中文文档,很早以前就听说了embed form,但一直没有机会实际应用, 昨天项目的新需求让我又想起了embed form, 所以又翻出了以前看过的文档, 仔细复习一遍, 同时也翻译出来分享个各位战友们。这是小弟的第一篇译文,难免有错误和遗漏,希望大家多包涵,多提宝贵意见。 – maker 2009.6.19

第一部分. 一对一关联内嵌表单

Symfony 1.2 添加了很多令人兴奋的新特性,并已经成为了一个很好很强大的PHP开发框架。 其中的一个特性是将一个Form嵌入另一个Form中。那么这意味着什么呢?

第一个模型如下图所示:

company_contact 上图是一个公司和联系方式的一对一关系模型。

这是我们的 schema.yml:

  1. propel:
  2. _attributes:
  3. package: lib.model
  4. defaultIdMethod: native
  5. company:
  6. _attributes: { phpName: Company }
  7. id: { type: INTEGER, size: ‘11′, primaryKey: true, autoIncrement: true, required: true }
  8. name: { type: VARCHAR, size: ‘255′, required: true }
  9. contact_id: { type: INTEGER, size: ‘11′, required: false, foreignTable: contact, foreignReference: id, onDelete: SET NULL, onUpdate: RESTRICT }
  10. _indexes: { company_FI_1: [contact_id] }
  11. contact:
  12. _attributes: { phpName: Contact }
  13. id: { type: INTEGER, size: ‘11′, primaryKey: true, autoIncrement: true, required: true }
  14. first_name: { type: VARCHAR, size: ‘255′, required: true }
  15. last_name: { type: VARCHAR, size: ‘255′, required: true }
  16. company_id: { type: INTEGER, size: ‘11′, required: false, foreignTable: company, foreignReference: id, onDelete: SET NULL, onUpdate: RESTRICT }
  17. _indexes: { contact_FI_1: [company_id] }

要注意的是这里的两个外键并不是必须存在(required)的,但是必须有了这两个外键我们才能将Contact Form嵌入到Company Form。

现在我们已经有了Schema, 让我们生成sql语句,模型(models), 表单(forms), 过滤器(filters), 并且创建数据表。

  1. $ php symfony propel:build-sql
  2. $ php symfony propel:build-model
  3. $ php symfony propel:build-forms
  4. $ php symfony propel:build-filters
  5. $ php symfony propel:insert-sql –env=dev

译者注:上面这组命令我们也可以简单的使用一个命令来完成

  1. $ php symfony propel:build-all

现在我们使用symfony中的admin generator来生成一个模块, 来看看如何生成和操作他们之间的关联。

  1. $ php symfony propel:generate-admin backend Company

我们生成了如下图所示的模块:

company_1现在如果我们点击“New”链接我们将看到界面如下:

company_2

注意外键”contact_id”被admin generator处理成一个下拉列表,当然这不是我们想要的结果,我们需要在新建Company的同时创建Contact. 感谢symfony 1.2 支持表单内嵌, 这会使我们的工作变得非常简单。

首先打开 “CompanyForm.class.php” 并且输入代码如下:

  1. public function configure() {
  2. // get Contact model object
  3. $contact = $this->getObject()->getContact();
  4. // contact object is null
  5. if (is_null($contact)) {
  6. // create a new Contact object
  7. $contact = new Contact();
  8. // set the copmany of the newly created object to the current company
  9. $contact->setCompany($this->getObject());
  10. // set the contact of the current company
  11. $this->getObject()->setContact($contact);
  12. }
  13. // create a new contact form
  14. $contact_form = new ContactForm($contact);
  15. // embed the contact form in the current company form
  16. $this->embedForm(‘contact’, $contact_form);
  17. // remove the contact_id from the form
  18. unset($this['contact_id']);
  19. }

接下来,打开ContactForm.class.php 并输入代码如下:

  1. public function configure() {
  2. unset($this['company_id']);
  3. }

现在修改模型类Company.php,在删除Contact的同时删除关联的Company

  1. public function delete(PropelPDO $con = null) {
  2. $this->getContact()->delete($con);
  3. parent::delete($con);
  4. }

最后一点也是很重要的,编辑generator.yml如下(这一步不是必须得) :

  1. generator:
  2. class: sfPropelGenerator
  3. param:
  4. model_class:           Company
  5. theme:                 admin
  6. non_verbose_templates: true
  7. with_show:             false
  8. singular:              ~
  9. plural:                ~
  10. route_prefix:          company
  11. with_propel_route:     1
  12. config:
  13. actions: ~
  14. fields:
  15. contact_id: { label: Company Contact }
  16. list:
  17. display: [=name, contact]
  18. filter:  ~
  19. form:    ~
  20. edit:    ~
  21. new:     ~

现在进入新建”Company”页面你会看到如图所示:

company_3尝试添加,编辑和删除一些记录以便确认一切是正确的。

company_4

company_5

第二部分. 一对多关联的内嵌表单

在文章的第一部分我们讲解了如何实一对一关联的表单内嵌。但是我们经常需要在编辑父对象的时候编辑或者添加子对象, 这并不是我们要使用admin generator的原因,总之在这部分文章里我们将要讲解一对多关系的表单内嵌。

在开始之前,我们看到的是最终要实现的CategoryForm。

embed_2

本文需要的文件

Ok, 我们开始吧,考虑下面这个schema:

  1. category:
  2. _attributes: { phpName: Category }
  3. id: { type: INTEGER, size: ‘11′, primaryKey: true, autoIncrement: true, required: true }
  4. name: { type: VARCHAR, size: ‘255′, required: true }
  5. created_at: { type: TIMESTAMP, required: false }
  6. updated_at: { type: TIMESTAMP, required: false }
  7. subcategory:
  8. _attributes: { phpName: Subcategory }
  9. id: { type: INTEGER, size: ‘11′, primaryKey: true, autoIncrement: true, required: true }
  10. name: { type: VARCHAR, size: ‘255′, required: true }
  11. category_id: { type: INTEGER, size: ‘11′, required: true, foreignTable: category, foreignReference: id, onDelete: CASCADE, onUpdate: RESTRICT }
  12. created_at: { type: TIMESTAMP, required: false }
  13. updated_at: { type: TIMESTAMP, required: false }

为了实现想要的效果,我们需要需要采取以下步骤

  1. 修改CategoryForm去包含当前分类所有的子分类的内嵌表单。
  2. 修改Widget中的子分类的name
  3. 修改CategoryForm添加一个空白的创建新子分类的表单。
  4. 重写sfForm类的bind方法,如果name域是空白则跳过保存(saving)和验证(validating)新子分类的表单。
  5. 在SubcategoryForm去掉全部的域(fields)

为当前分类插入全部子分类的内嵌表单[第1,2,3步]

  1. // lib/forms/CategoryForm.class.php
  2. public function configure() {
  3. // remove timestamps
  4. unset($this['created_at'], $this['updated_at']);
  5. // embed forms only when editing
  6. if (!$this->isNew()) {
  7. // embed all subcategory forms
  8. foreach ($this->getObject()->getSubcategorys() as $subcategory) {
  9. // create a new subcategory form for the current subcategory model object
  10. $subcategory_form = new SubcategoryForm($subcategory);
  11. // embed the subcategory form in the main category form
  12. $this->embedForm(’subcategory’.$subcategory->getId(), $subcategory_form);
  13. // set a custom label for the embedded form
  14. $this->widgetSchema['subcategory'.$subcategory->getId()]->setLabel(‘Subcategory: ’.$subcategory->getName());
  15. // change the name widget to sfWidgetFormInputDelete
  16. $this->widgetSchema['subcategory'.$subcategory->getId()]['name'] = new sfWidgetFormInputDelete(array(
  17. ‘url’ => ‘category/deleteSubcategory’, // required
  18. ‘model_id’ => $subcategory->getId(), // required
  19. ‘confirm’ => ‘Sure???’, // optional
  20. ));
  21. }
  22. // create a new subcategory form for a new subcategory model object
  23. $subcategory_form = new SubcategoryForm();
  24. // embed the subcategory form in the main category form
  25. $this->embedForm(’subcategory’, $subcategory_form);
  26. // set a custom label for the embedded form
  27. $this->widgetSchema['subcategory']->setLabel(‘New Subcategory’);
  28. }
  29. }

重写bind方法

  1. public function bind(array $taintedValues = null, array $taintedFiles = null) {
  2. // remove the embedded new form if the name field was not provided
  3. if (is_null($taintedValues['subcategory']['name']) || strlen($taintedValues['subcategory']['name']) === 0 ) {
  4. unset($this->embeddedForms['subcategory'], $taintedValues['subcategory']);
  5. // pass the new form validations
  6. $this->validatorSchema['subcategory'] = new sfValidatorPass();
  7. else {
  8. // set the category of the new subcategory form object
  9. $this->embeddedForms['subcategory']->getObject()->setCategory($this->getObject());
  10. }
  11. // call parent bind method
  12. parent::bind($taintedValues, $taintedFiles);
  13. }

在SubcategoryForm中的域

  1. public function configure(){
  2. unset($this['created_at'], $this['updated_at'], $this['category_id']);
  3. }

现在我们在分类模块下创建deleteSubcategory动作

  1. // apps/backend/modules/category/actions/actions.class.php
  2. public function executeDeleteSubcategory(sfWebRequest $request) {
  3. $sub_category = SubcategoryPeer::retrieveByPk($request->getParameter(‘id’));
  4. $sub_category->delete();
  5. $this->redirect(‘@category_edit?id=’.$sub_category->getCategory()->getId());
  6. }

就是这样了,我希望你会喜欢这篇文章。

第三部分. 内嵌表单的本地化

在本系列文章的上一部分我们介绍了在父对象中编辑多个子对象的方法。 在本部分钟我们将给子对象添加本地化行为, 为了更清楚的知道我们要做的事先看一下最终的效果。

embed_i18n

在开始之前,如果你没准备好,我强烈建议你去阅读一下第1,2部分。 OK, 我们开始吧,我们将要修改以下文件:

  • CategoryForm.class.php 分类模型的表单
  • SubcategoryI18nForm.class.php 子分类模型的本地化模型的表单
  • Subcategory.class.php 子分类模型

本文的附件

Schema.yml

  1. category:
  2. _attributes: { phpName: Category }
  3. id: { type: INTEGER, size: ‘11′, primaryKey: true, autoIncrement: true, required: true }
  4. name: { type: VARCHAR, size: ‘255′, required: true }
  5. created_at: { type: TIMESTAMP, required: false }
  6. updated_at: { type: TIMESTAMP, required: false }
  7. subcategory:
  8. _attributes: { phpName: Subcategory, isI18N: true, i18nTable: subcategory_i18n }
  9. id:          { type: integer, required: true, primaryKey: true, autoincrement: true }
  10. category_id: { type: INTEGER, size: ‘11′, required: true, foreignTable: category, foreignReference: id, onDelete: CASCADE}
  11. created_at: { type: TIMESTAMP, required: false }
  12. updated_at: { type: TIMESTAMP, required: false }
  13. subcategory_i18n:
  14. _attributes: { phpName: SubcategoryI18n }
  15. id:          { type: integer, required: true, primaryKey: true, foreignTable: subcategory, foreignReference: id, onDelete: CASCADE }
  16. culture:     { isCulture: true, type: varchar, size: 7, required: true, primaryKey: true }
  17. name:        { type: varchar, size: 50 }

SubcategoryI18nForm.class.php

  1. public function configure() {
  2. unset($this['culture'], $this['id']);
  3. }

Subcategory.class.php

  1. public function getI18nObject($culture = ‘en’) {
  2. $this->setCulture($culture);
  3. $i18ns = $this->getSubcategoryI18ns();
  4. if (isset($i18ns[0])) {
  5. return $i18ns[0];
  6. }
  7. return null;
  8. }

CategoryForm.class.php

  1. public function configure() {
  2. // remove timestamps
  3. unset($this['created_at'], $this['updated_at']);
  4. // embed forms only when editing
  5. if (!$this->isNew()) {
  6. $user_culture = sfContext::getInstance()->getUser()->getCulture();
  7. // embed all subcategory forms
  8. foreach ($this->getObject()->getSubcategorys() as $subcategory) {
  9. // get the subcategory_i18n model object relative to the current user culture
  10. $subcategory_i18n_object = $subcategory->getI18nObject($user_culture);
  11. // create a new subcategory_i18n form for the current subcategory model object
  12. $subcategory_i18n_form = new SubcategoryI18nForm($subcategory->getI18nObject(‘en’));
  13. // get widget schema of subcategory_i18n form
  14. $subcategory_i18n_form_widget_schema = $subcategory_i18n_form->getWidgetSchema();
  15. // set the input delete widget
  16. $subcategory_i18n_form_widget_schema['name'] = new sfWidgetFormInputDelete(array(
  17. ‘url’ => ‘category/deleteSubcategory’, // required
  18. ‘model_id’ => $subcategory->getId(), // required
  19. ‘confirm’ => ‘Sure???’, // optional
  20. ));
  21. // create a new subcategory form for the current subcategory model object
  22. $subcategory_form = new SubcategoryForm($subcategory);
  23. // embed the i18n form
  24. $subcategory_form->embedForm(’subcategory_i18n’.$subcategory_i18n_object->getId(), $subcategory_i18n_form);
  25. // subcategory form widget schema
  26. $subcategory_form_widget_schema = $subcategory_form->getWidgetSchema();
  27. // disable label
  28. $subcategory_form_widget_schema['subcategory_i18n'.$subcategory_i18n_object->getId()]->setLabel(false);
  29. // embed the subcategory form in the main category form
  30. $this->embedForm(’subcategory’.$subcategory->getId(), $subcategory_form);
  31. // set a custom label for the embedded form
  32. $this->widgetSchema['subcategory'.$subcategory->getId()]->setLabel(‘Subcategory: ’.$subcategory->getName());
  33. }
  34. // create a new subcategory form for a new subcategory model object
  35. $subcategory_form = new SubcategoryForm();
  36. // create a new subcategory form for a new subcategory_i18n model object
  37. $subcategory_i18n_form = new SubcategoryI18nForm();
  38. // embed the subcategory_i18n form in the parent subcategory form
  39. $subcategory_form->embedForm(’subcategory_i18n’, $subcategory_i18n_form);
  40. // subcategory form widget schema
  41. $subcategory_form_widget_schema = $subcategory_form->getWidgetSchema();
  42. // disable label
  43. $subcategory_form_widget_schema['subcategory_i18n']->setLabel(false);
  44. // embed the subcategory form in the main category form
  45. $this->embedForm(’subcategory’, $subcategory_form);
  46. // set a custom label for the embedded form
  47. $this->widgetSchema['subcategory']->setLabel(‘New Subcategory’);
  48. }
  49. }
  50. public function bind(array $taintedValues = null, array $taintedFiles = null) {
  51. if(!$this->isNew()) {
  52. $user_culture = sfContext::getInstance()->getUser()->getCulture();
  53. // remove the embedded new form if the name field was not provided
  54. if (is_null($taintedValues['subcategory']['subcategory_i18n']['name']) || strlen($taintedValues['subcategory']['subcategory_i18n']['name']) === 0 ) {
  55. unset($this->embeddedForms['subcategory'], $taintedValues['subcategory']);
  56. // pass the new form validations
  57. $this->validatorSchema['subcategory'] = new sfValidatorPass();
  58. else {
  59. // set the category of the new subcategory form object
  60. $this->embeddedForms['subcategory']->getObject()->setCategory($this->getObject());
  61. // get subcategory embedded forms
  62. $subcategory_embedded_forms = $this->embeddedForms['subcategory']->getEmbeddedForms();
  63. // set subcategory parent of the subcategory_i18n model object
  64. $subcategory_embedded_forms['subcategory_i18n']->getObject()->setSubcategory($this->embeddedForms['subcategory']->getObject());
  65. // set the culture of the subcategory_i18n model object
  66. $subcategory_embedded_forms['subcategory_i18n']->getObject()->setCulture($user_culture);
  67. }
  68. }
  69. // call parent bind method
  70. parent::bind($taintedValues, $taintedFiles);
  71. }

正如你所看到的,这是功能需要你复制和粘贴大量的代码,这就是为什么我在使用扩展的Admin Generator,  为了当你生成管理模块的时候有此功能可用。

2009-05-25

怎么在app中构造其它app的链接(二)

类归于: symfony — 标签:zhuozi @ 17:15

写一个class

// apps/backend/config/backendConfiguration.class.php
class backendConfiguration extends sfApplicationConfiguration
{
protected $frontendRouting = null;
public function generateFrontendUrl($name, $parameters = array())
{
return 'http://frontend.example.com'.$this->getFrontendRouting()
->generate($name, $parameters);
}
public function getFrontendRouting()
{
if (!$this->frontendRouting)
{
$this->frontendRouting = new sfPatternRouting(new sfEventDispatcher());
$config = new sfRoutingConfigHandler();
$routes = $config->evaluate(array(sfConfig::get('sf_apps_dir').
'/frontend/config/routing.yml'));
$this->frontendRouting->setRoutes($routes);
}
return $this->frontendRouting;
}
}

在action中可以用下面的动作,就可以跳到其它的app中的动作,下面的‘hello’,是frontend/config配置文件routing中的一条路由规则

$this->redirect($this->getContext()->getConfiguration()->
generateFrontendUrl('hello', array('name' => 'Bar')));


function link_to_frontend($name, $parameters)
{
return sfProjectConfiguration::getActive()->
generateFrontendUrl($name, $parameters);
}

« 较近文章早前文章 »

WordPress 所驱动