2011年5月30日 星期一

Symfony form phpant Class 6

例 6-8 – sfActions 常用方法
class mymoduleActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
// Retrieving request parameters
$password = $request->getParameter('password');
// Retrieving controller information
$moduleName = $this->getModuleName();
$actionName = $this->getActionName();
  // Retrieving framework core objects
$userSession = $this->getUser();
$response = $this->getResponse();
$controller = $this->getController();
$context = $this->getContext();
// Setting action variables to pass information to the template
$this->setVar('foo', 'bar');
$this->foo = 'bar'; // Shorter version
}
}


sfController: 控制器对象(->getController())
sfRequest: 请求对象 (->getRequest())
sfResponse: 应答对象 (->getResponse())
sfUser: 用户 session 对象 (->getUser())
sfRouting:路由对象(->getRouting())
sfMailer:邮件对象(->getMailer())
sfI18N:国际化对象 (->getI18N())
sfLogger: 日志对象 (->getLogger())
sfDatabaseConnection: 数据库链接对象 (- >getDatabaseConnection())




正常一般action的結尾 應該為
return sfView::SUCCESS; 

如果有錯 應該這樣結尾
return sfView::ERROR;
symfony 就会去寻找 actionNameError.php 模板。
 
如果你想用一个特别的视图,你可以这样结尾:
return 'MyResult'; 

如果根本就没有或不需要视图—例如,批处理文件的执行–应该这样结尾:
return sfView::NONE; 

用 sfView::NONE 越过视图层直接输出回应
public function executeIndex()
{
$this->getResponse()->setContent("<html><body>Hello, World!</body></html>");
return sfView::NONE;
}
// Is equivalent to
public function executeIndex()
{
return $this->renderText("<html><body>Hello, World!</body></html>");
}


例 6-10 – 避开视图层,但应答有 HTTP 头
public function executeRefresh()
{
$output = '<"title","My basic letter"],["name","Mr Brown">';
$this->getResponse()->setHttpHeader("X-JSON", '('.$output.')');
return sfView::HEADER_ONLY;
}

如果动作需要一个特殊的模板,去掉 return 声明, 用 setTemplate()方法
$this->setTemplate('myCustomTemplate');

public function executeIndex()
{
$this->setTemplate('myCustomTemplate');
}



From action to action 

跳到另一个动作

在一些情况下,一个动作结束时需要执行另一个动作。例如,一个处理表单提交的动作在更新数据库后通常被跳转到另一个动作上。
动作类里提供了两个方法可以执行另一个动作:
  • 如果动作转发给另一个动作:
  • $this->forward('otherModule', 'index');
  • 如果跳转到另一个动作:
  • $this->redirect('otherModule/index'); $this->redirect('http://www.google.com/'); NOTE forward 与 redirect 之后的动作代码不会被执行。这一点上与 return 语句是一样的。它们会抛出一个 sfStopException 异常来停止动作的执行; 这个异常稍后会被 symfony 截获然后忽略
选择转发或跳转有时并不容易。为了做出最好的选择,请记住转发在应用程序内 部进行,所以对于用户来说比较直接易懂。在用户的眼里,浏览器显示的 URL 和用户请求的 URL 是一样的。 相反地,跳转是一条发给用户浏览器的消息,包括一个新的请求并改变了最终的 URL。

如果一个表单通过 method="post"调用动作,你应该使用跳转。最大的优点是, 如果用户刷新页面,表单不会被重新提交;另外,如果用户点击后退键,浏览器会再显示表单,而不是询问用户是否要重新提交表单。

所以 sfActions 类有几个方法叫 forwardIf(), forwardUnless(), forward404If(), forward404Unless(), redirectIf(),redirectUnless()。这 些方法接受一个参数并且对它进行判断,如果判断结果是 true,xxxIf() 方法


表格 6-1 - sfWebRequest 对象里的方法
名称 功能 输出例子
请求信息
isMethod($method) 是POST还是GET方法 true或者false
getMethod() 请求方法名 'POST'
getHttpHeader('Server') HTTP头值 'Apache/2.0.59 (Unix) DAV/2 PHP/5.1.6'
getCookie('foo') 称作foo人cookie的值 'bar'
isXmlHttpRequest()* 是否是Ajax访问 true
isSecure() 是否是SSL访问 true
请求参数
hasParameter('foo') 请求里是否包含foo true或者false
getParameter('foo') Foo参数的值 bar
setParameterHolder()->getAll() 所有参数数组 array
URI相关信息
getUri() 完整的URI 'http://localhost/frontend_dev.php/mymodule/myaction'
getPathInfo() 路径信息 /mymodule/myaction'
getReferer() Referer(来源) http://localhost/frontend_dev.php/
getHost() 主机名 'localhost'
getScriptName() 前端控制器名 'frontend_dev.php'
客户端浏览器信息
getLanguages() 所有可接受的语言数组 Array( [0] => fr [1] => fr_FR [2] => en_US [3] => en )
getCharsets() 所有可接受的字符集数组 Array( [0] => ISO-8859-1 [1] => UTF-8 [2] => * )
getAcceptableContentTypes() 所有可接受的内容类型数组 Array( [0] => text/xml [1] => text/html
*只能用于prototype,Prototype,Mootools,和 jQuery库
** 有时会被代理服务器阻拦



短暂的属性

删除用户会话属性(如果不再需要这个属性了)是一个常见的问题。例如,在用户提交表单后,你想显示一个确认信息。 当处理表单的动作需要转发到另一个动作时,把信息从一个动作传到另一个动作唯一的办法就是把信息存在用户会话的属性里。在显示确认信息之后,你需要删除这 个属性。否则,这个属性就会 被存入会话里,一直到会话到期。
你只需要定义短暂的属性,而不需要去删除。因为短暂的属性在接受到下一个请 求后会自动删除,使用户会话更清洁。在动作里,你可以这样来定义短暂的属性:
$this->getUser()->setFlash('notice', $value);
用户看到这一页后,发出一个新的请求并触发了下一个动作。在这第二个动作里, 你可以这样取得属性的值:
$value = $this->getFlash('attrib');
删除用户会话属性(如果不再需要这个属性了)是一个常见的问题。例如,在用户提交表单后,你想显示一个确认信息。 当处理表单的动作需要转发到另一个动作时,把信息从一个动作传到另一个动作唯一的办法就是把信息存在用户会话的属性里。在显示确认信息之后,你需要删除这 个属性。否则,这个属性就会 被存入会话里,一直到会话到期。
你只需要定义短暂的属性,而不需要去删除。因为短暂的属性在接受到下一个请 求后会自动删除,使用户会话更清洁。在动作里,你可以这样来定义短暂的属性:
$this->getUser()->setFlash('notice', $value);
用户看到这一页后,发出一个新的请求并触发了下一个动作。在这第二个动作里, 你可以这样取得属性的值:
$value = $this->getFlash('attrib');


会话管理


smfony 把ID 存在客户端的 cookies 上。symfony 的会话 cookies 就叫 symfony,
你可以在factories.yml 設定名稱。
例 6-17 - 在 apps/frontend/config/factories.yml 里,改变会话的 Cookie 名称
all:
   storage:
     class: sfSessionStorage
     param:
       session_name: my_cookie_name


访问限制

例 6-20 - 设置访问限制, 在 apps/frontend/modules/mymodule/config/security.yml 里
read:
   is_secure: false # All users can request the read action
update:
   is_secure: true # The update action is only for authenticated users
delete:
   is_secure: true # Only for authenticated users
   credentials: admin # With the admin credential
all:
   is_secure: false # false is the default value anyway



访问授权

如果要调用设有权限的动作,用户必须被认证后并有相应的证书。你可以用sfUser 对象扩展用户的权限。 setAuthenticated()方法可以改变用户的认证状态,isAuthenticated()方法可以检查用户的认证状态。 例 6-22 是一个用户认证的简单例子。
例 6-22 – 设置用户的认证状态
class myAccountActions extends sfActions
{
public function executeLogin($request)
{
if ($request->getParameter('login') === 'foobar')
{
$this->getUser()->setAuthenticated(true);
}
}
public function executeLogout()
{
$this->getUser()->setAuthenticated(false);
}
}



過濾器 filter還沒看

symfony from phpant class4

<p>Hello, world!</p>
<?php if ($hour >= 18): ?>
<p>Or should I say good evening? It is already <?php echo $hour ?>.</p>
<?php endif; ?>
<form method="post" action="<?php echo url_for('content/update') ?>">
<label for="name">What is your name?</label>
<input type="text" name="name" id="name" value="" />
<input type="submit" value="Ok" />
<?php echo link_to('I never say my name', 'content/update?name=anonymous') ?>
</form>


使用url_for直接前往指定頁面
link_to 秀出 顯示字樣與傳送所帶參數


第一種
<?php echo link_to('I never say my name', 'content/update?name=anonymous',
array(
'class' => 'special_link',
'confirm' => 'Are you sure?',
'absolute' => true
)) ?>

第2種
// Option argument as a string
<?php echo link_to('I never say my name', 'content/update?name=anonymous',
'class=special_link confirm=Are you sure? absolute=true') ?> 

都相當於底下
// Both calls output the same
=> <a class="special_link" onclick="return confirm('Are you sure?');"
href="http://localhost/frontend_dev.php/content/update/name/anonymous">
I never say my name</a>


get value from action
public function executeUpdate($request)
{
$this->name = $request->getParameter('name');
}
  


get the value from  module 
<?php echo $sf_params->get('name') ?>!</p>

判斷參數是否存在
<?php if ($sf_params->has('name')): ?> 

當參數不存在時使用預設值 (第2個參數 )
<p>Hello, <?php echo $sf_params->get('name', 'John Doe') ?>!</p>



第五章 配置symfony

編寫yml時(symfony的預設格式,但也可以使用ini與xml)
1.非标准的字符串要用单引号包起来

error1: This field is compulsory
error2: ' This field is compulsory '
error3: 'Don''t leave this field blank' # Single quotes must be doubled
error4: 'Enter a # symbol to define an extension number'
i18n: 'false' # if we left off the quotes here, a boolean false would 
2.利用特殊字符头(> 或 |)与一个缩进,长的字符串可以跨行表示

# Folded style, introduced by >
# Each line break is folded to a space
# Makes YAML more readable
accomplishment: >
Mark set a major league
home run record in 1998.
# Literal style, introduced by |
# All line breaks count
# Indentation doesn't appear in the resulting string
stats: |
65 Home Runs
0.278 Batting Average
3.如果要定义数组,需要用方括号把元素括起来或者使用展开的减号语法
# Shorthand syntax for arrays
players: [ Mark McGwire, Sammy Sosa, Ken Griffey ]
# Expanded syntax for arrays
players:
- Mark McGwire
- Sammy Sosa
- Ken Griffey


sfConfig::get()  set() add()  等等    
配置文件名有关的前缀 (sf_ 代表 settings.yml,,app_ 代表 app.yml, mod_ 代表module.yml)

 YAML 文件可以包含 PHP  
all:
   translation:
      format: <?php echo (sfConfig::get('sf_i18n') === true ? 'xliff' : null

同时,因为echo语句不自动添加换行符,为了保证YAML文件的结构你需要输出一个”\n”来换行。
all:
   translation:
     format: <?php echoln(sfConfig::get(’sf_i18n’) == true ? ‘xliff’ : ‘none’) ?>


使用 sfYaml 类把 YAML 转换成一个数组
$test = sfYaml::load('/path/to/test.yml');
print_r($test); 

Array(
[house] => Array(
[family] => Array(
[name] => Doe
[parents] => Array(
[0] => John
[1] => Jane
)
[children] => Array(
[0] => Paul
[1] => Mark
[2] => Simone
)
)
[address] => Array(
[number] => 34
[street] => Main Street
[city] => Nowheretown
[zipcode] => 12345
)
)
)

 
 

2011年5月27日 星期五

轉錄-帶著筆記學程式

  1. 模版以外使用 Helper
  2. - sfProjectConfiguration::getActive()->loadHelpers($helpers)
  3.   - 如 TextHelper 則 $helpers = Text
  4.  
  5. 模版中使用不是預設加載的幫助類
  6. - < ?php echo use_helper('Text', 'JavaScript') ?>
  7.  
  8. 自己寫的 Helper 可以放於
  9. - app/frontend/lib/helper
  10. - lib/helper
  11.  
  12. 默認佈局(Layout)
  13. - templates/
  14. - apps/frontend/templates/layout.php
  15.  
  16. 模版中的變數
  17. - $sf_context: 環境對象 (context object) (sfContext 物件)
  18. - $sf_request: 請求對象 (sfRequest 物件)
  19. - $sf_params : 請求的參數
  20. - $sf_user   : 當前用戶的 Session 對象 (sfUser 物件)
  21.  
  22. - $sf_request->getParameter('xxx')
  23. - $sf_params->get('xxx')
  24. - $this->getParameter('xxx')  [用於 action 上]
  25.  
  26. 局部文件 (Partials)
  27. - 以 _ 開頭
  28. - 載入用 include_partial 函數,省略 _ 和 .php
  29. - 如在同一 Module 直接輸入模板名稱則可
  30.   - 否則需要使用 module_name/template_file_name
  31.   - 如果在全域中 global/template_file_name
  32.  
  33. - 傳送參數給局部文件可以通過
  34.   - include_partial(template_name, array('param1'=>value1, …))
  35.  
  36. - action 中調用
  37.   - $this->renderPartial('my_module/my_template_name');
  38.  
  39. 組件 (Components)
  40. - 存放於 action/components.class.php
  41. - 和 action 一樣以 execute 開頭
  42. - View 以 _my_component_execute_name.php 命名
  43.   - 即 executeHeadlines -> _headlines.php
  44. - 模板中使用
  45.   - include_component(component_name, action_name)
  46.   - include_component(component_name, action_name, array('param1'=>value1,….))
  47.     - action 內 $this->param1
  48.     - 模版內 $param1
  49.  
  50. 槽 (Slots)
  51. - 用 include_slot(slot_name) 檢查是否定義了這個槽
  52. - 可用 slot('slot_name') , end_slot() 定義 slot 區塊(block)
  53. - 如
  54.   a.php
  55.     - include_slot('title')
  56.   b.php
  57.     - slot('title', 'this is a test')
  58.     
  59. View.yml
  60. - apps/my_app/modules/my_modul/config/view.yml 只作用於自身模組的個別 action 覆蓋
  61. - apps/my_app/modules/my_modul/config/view.yml 的 all 會對所有動作進行覆蓋
  62. - 默認視圖文件
  63.   - apps/frontend/conf/view.yml
  64. - action 中設置 meta, head 頭
  65.   - $this->getResponse()
  66.     - setContentType, setHttpHeader, setStatusCode(code, message)
  67.     - addMeta, setTitle, addStyleSheet, addJavaScript
  68.     - setCookie(name, content, expire, path, domain)
  69.     
  70. - view.yml
  71.   - set 是字串 ""
  72.   - add 是數組 [1, 2, 3]
  73.  
  74. - 標題 view.yml
  75.   - indeSuccess
  76.     - metas
  77.       - title: xxxxx
  78.     - stylesheet: [1, 2, 3]
  79.     - javascript: [script]
  80.     
  81.       * [-main.js, main2.js] 則刪掉 main.js
  82.       * [-*] 則刪掉所掉
  83.       * [special: { position: first }] 則優先加載
  84.       * [http://main.js, paper:{ raw_name: true }] 直接使用 url
  85.     
  86. - action 中
  87.   - $this->getResponse()->addStylesheet('mystyle1');
  88.   - $this->getResponse()->addJavascript('myscript');
  89.   - $this->getResponse()->addJavascript('myscript', 'first'); 優先加載
  90.   - $this->getResponse()->addJavascript('myscript', '', array('raw_name' => true)); 直接使用 url
  91. - 模版中
  92.   - use_stylesheet('xxx')
  93.   - use_javascript('xxx')
  94.   - use_javascript('xxx', 'first') 優先加載
  95.   - use_javascript('xxx', '', array('raw_name' => true)) 直接使用 url
  96.  
  97. - 指定布局文件
  98.   - indexSuccess
  99.     - layout: abc
  100.     - has_layout: false // 去掉布局
  101.  
  102.   - $this->setLayout('abc') // action 中
  103.   - $this->setLayout(false) // 去掉布局
  104.  
  105.   - decorate_with('abc') // 模板 中
  106.   - decorate_with(false) // 去掉布局
  107.  
  108. - XSS 安全
  109.   - frontend/config/settings.yml
  110.     - all:
  111.       - .settings:
  112.         - escaping_strategy: true
  113.         - escaping_method: ESC_SPECIALCHARS ****
  114.   - 取得過濾的資料
  115.     - $sf_data->get('test');
  116.     - $sf_data['test'];
  117.   - 未過濾資料
  118.     - $sf_data->getRaw('test');
  119.     
  120.   ****
  121.   - ESC_RAW: 不轉義
  122.   - ESC_SPECIALCHARS: htmlspecialchars()。
  123.   - ESC_ENTITIES: htmlentites() ENT_QUOTES
  124.   - ESC_JS: 將 HTML 轉義,使其可被放於 JavaScript 字串中
  125.   - ESC_JS_NO_ENTITIES:轉變成 JavaScript 中可使用的字串,如 alert
  126.  
  127.   ****
  128.   轉義後 $sf_user,$sf_request,$sf_param, $sf_context 也會被轉義
  129.   如果需要使用原數據,則取用 ESC_RAW 作傳遞
第 08 章
  1. 生成模型
  2. - php symfony cc (如找不到就先清理)
  3. - php symfony doctrine:build-model
  4.  
  5. 基礎: lib/model/doctrine/base (每次 build 將自動生成)
  6. 實際: lib/model/doctrine (改動則於此,build 不影響)
  7.  
  8. 取數據
  9. $article = new Article();
  10. $article->setTitle('this is a test');
  11. $acticle->getTitle();
  12.  
  13. $article->fromArray(array(
  14. 'title' => "this is a test"
  15. 'content' => "this is a content"
  16. ));
  17.  
  18. $article->save();
  19.  
  20. $article->getId(); // 取得 last_insert_id
  21. $article->isNew();
  22. $article->isModified();
  23.  
  24. $article = Doctrine_Core::getTable("article")->find(123);
  25.  
  26. --
  27. $comment = new Comment();
  28. $comment->setTitle("this is test");
  29. $comment->setContent("this is content");
  30. $comment->setArticle($article);
  31.  
  32. $comment->setArticleId($article->getId());
  33. $comment->getArticle()->getTitle();
  34.  
  35. $article->getComments(); // 一篇文章對多篇回應
  36.  
  37. $comment->delete();
  38.  
  39. ---
  40. 一般查詢
  41. $q = Doctrine_Core::getTable('Article')->createQuery();
  42. $articles = $q->execute();
  43.  
  44. $q = Doctrine_Core::getTable('Comment')->createQuery('c')
  45.      ->where('c.author = ?', 'Steve')
  46.      ->leftJoin('c.Article a')
  47.      ->andWhere('a.content LIKE ?', '%enjoy%')
  48.      ->orderBy('c.created_at ASC');
  49. $comments = $q->execute();
  50.  
  51. Table 類的提供: findAll(), findBy*(), 和findOneBy*(), fetchOne()
  52.  
  53. ---
  54. PDO 的查詢
  55.  
  56. connection = Doctrine_Manager::connection();
  57. $query = 'SELECT MAX(created_at) AS max FROM blog_article';
  58. $statement = $connection->execute($query);
  59. $statement->execute();
  60. $resultset = $statement->fetch(PDO::FETCH_OBJ);
  61. $max = $resultset->max;
  62.  
  63. ---
  64. Timestampable 自動設置 created_at 和 updated_at
  65.  
  66. schema.yml 可以分拆成多個文件
  67. - config/doctrine/business-schema.yml
  68. - config/doctrine/stats-schema.yml
  69.  
  70. 分表.不同表用不同的 connection
  71. 1. 在 database.yml 中定義 doctrine 和 doctrine_bis
  72. 2. business-schema.yml 加入 connections: doctrine
  73. 3. stats-schema.yml 加入 connections: doctrine_bis
  74.  
  75. 由資料庫中生成 schema.yml
  76. php symfony doctrine:build-schema
第 9 章
  1. 路由規則
  2. - routing.yml
  3.  
  4. routing.yml
  5. - article_by_title:
  6.   - url:    articles/:subject/:year/:title.html
  7.   - param:  { module: article, action: permalink }
  8.  
  9. 請求: http://www.example.com/articles/finance/2010/activity-breakdown.html
  10. 得出:
  11. 'module'  => 'article'
  12. 'action'  => 'permalink'
  13. 'subject' => 'finance'
  14. 'year'    => '2010'
  15. 'title'   => 'activity-breakdown'
  16.  
  17. url_for(url) 函數會將內部 URL 轉化為外部 URL
  18. link_to(label, url, array(class=>'', target='')) 會自動呼叫 url_for 轉換和處理
  19. button_to(label, url)
  20. from_tag(url)
  21.  
  22. apps/frontend/settings.yml 中的 no_script_name 控制 URL 顯示
  23. - false 時則顯示 index.php/ 或 myapp_dev.php/
  24. - true 則會隱藏
  25. - true 時,則代表其不在測試/開發環境而是在 prod 生產/正式環境 ***
  26.  
  27. mod_rewrite
  28. - 文件位於 myproject/web/.htaccess
  29.  
  30. 檢查 post, get
  31. - $this->request->isMethod('post')
  32.  
  33. link_to 為 post
  34. - link_to(label, url, 'post=true')
  35.  
  36. 除了 post 還有 encode 和 absolute
  37. - encode 輸出無法識別的東西,主要用來加密 email
  38. - absolute 輸出完整網址
  39.  
  40. 取得/解釋 Rout URL
  41. - http://myapp.example.com/article/21
  42.  
  43.   - $routing = $this->getContext()->getRouting();
  44.  
  45.   - $uri = $routing->getCurrentInternalUri();
  46.   > article/read?id=21
  47.  
  48.   - $uri = $routing->getCurrentInternalUri(true);
  49.   > @article_by_id?id=21
  50.  
  51.   - $rule = $routing->getCurrentRouteName();
  52.   > article_by_id
  53.  
  54.   - $module = $this->getParameter('module');
  55.   - $action = $this->getParameter('action');
  56.  
  57. 由外部 URL 轉換成內部 URL
  58. - $uri = 'article/read?id=21';
  59.  
  60.   - $url = $this->getController()->genUrl($uri);
  61.   > /article/21
  62.  
  63.   - $url = $this->getController()->genUrl($uri, true);
  64.   > http://myapp.example.com/article/21
第 10 章
  1. action 中
  2. ---
  3. $this->form = new sfForm();
  4. $this->form->setWidgets(array(
  5. 'name'    => new sfWidgetFormInputText(),
  6. 'email'   => new sfWidgetFormInputText(array('default' => 'me@example.com')),
  7. 'subject' => new sfWidgetFormChoice(array('choices' => array('Subject A', 'Subject B', 'Subject C'))),
  8. 'message' => new sfWidgetFormTextarea(),
  9. ));
  10.  
  11. 模版中
  12. < ?php echo $form; ?>
  13.  
  14. 如果要自定義
  15. < ?php echo $from['name']->renderRow(); ?>
  16.  
  17. 如果需要改變 HTML 屬性
  18. - 第一個參數是屬性
  19. - 第二個參數是可選,替換標籤
  20. < ?php echo $form['name']->renderRow(array('size' => 25, 'class' => 'foo'), 'Your Name') ?>
  21.  
  22. 可分開來顯示 (則不用 table 結構,自定義)
  23. - render() (for the widget), renderError(), renderLabel(), and renderHelp()
  24. - 即
  25. <ul>
  26. < ?php foreach ($form as $field): ?>
  27. <li>
  28. < ?php echo $field->renderLabel() ?>
  29. < ?php echo $field->render() ?>
  30. </li>
  31. < ?php endforeach; ?>
  32. </ul>
  33. - 或
  34. <ul>
  35. < ?php echo $form->renderUsing('list') ?>
  36. </ul>
  37. setWidget 設置
  38. - $form->setWidget('full_name', new sfWidgetFormInput(array('default' => 'John Doe')));
  39. >
  40.   <label for="full_name">Full Name</label>
  41.   <input type="text" name="full_name" id="full_name" value="John Doe" />
  42.  
  43. - $form->setWidget('address', new sfWidgetFormTextarea(array('default' => 'Enter your address here'), array('cols' => 20, 'rows' => 5)));
  44. >
  45.   <label for="address">Address</label>
  46.   <textarea name="address" id="address" cols="20" rows="5">Enter your address here</textarea>
  47.  
  48. - $form->setWidget('pwd', new sfWidgetFormInputPassword());
  49. >
  50.   <label for="pwd">Pwd</label>
  51.   <input type="password" name="pwd" id="pwd" />
  52.  
  53. - $form->setWidget('id', new sfWidgetFormInputHidden(array('default' => 1234)));
  54. >
  55.   <input type="hidden" name="id" id="id" value="1234" />
  56.  
  57. - $form->setWidget('single', new sfWidgetFormInputCheckbox(array('value_attribute_value' => 'single', 'default' => true)));
  58. >
  59.   <label for="single">Single</label>
  60.   <input type="checkbox" name="single" id="single" value="true" checked="checked" />
  61.  
  62.  
  63. 上傳文件組件和預覽
  64. - $form->setWidget('picture', new sfWidgetFormInputFile());
  65. >
  66.   <label for="picture">Picture</label>
  67.   <input id="picture" type="file" name="picture"/>
  68.  
  69. - $form->setWidget('picture', new sfWidgetFormInputFileEditable(array('default' => '/images/foo.png')));
  70.  
  71. 驗證表單
  72. $this->form->setValidators(array(
  73. 'name' => new sfValidatorString(),
  74. 'email' => new sfValidatorEmail(),
  75. 'message' => new sfValidatorString(array('min_length' => 4))
  76. ));
  77.  
  78. if ($request->isMethod('post')) {
  79. $this->from->bind(/* 用戶提交數據 */);
  80. if ($this->form->isValid()) {
  81. xxx
  82. }
  83. }
  84.  
  85. 用戶提交數據解決
  86. - 使用 $this->form->setNameFormat('contact[%s]'); 定義表單
  87. - 之後表單的 key value 就會被 contact 包裹成為 $contact 的陣列
  88. - 則可以通過以下方法 bind,從而只取得表單而不是其他資料
  89.   $this->form->bind($request->getParameter('contact'));
  90.  
  91. 顯示全局域錯誤
  92. < ?php if ($form->hasErrors()): ?>
  93. The form has some errors you need to fix.
  94. < ?php endif; ?>
  95.  
  96. 使用驗證器必須每個欄位都定義,如果是可選,可設置 required => false
  97. $this->form->setValidators(array(
  98. 'name' => new sfValidatorString(),
  99. 'email' => new sfValidatorEmail(array('required' => false)),
  100. 'message' => new sfValidatorString(array('min_length' => 4))
  101. ));
  102.  
  103. 驗證兩個條件以上,可用 sfValidatorAnd / sfValidatorOr
  104. $this->form->setValidators(array(
  105. 'name' => new sfValidatorString(),
  106. 'email' => new sfValidatorAnd(
  107. new sfValidatorEmail(),
  108. new sfValidatorString(array('min_length' => 4)),
  109. ),
  110. 'message' => new sfValidatorString(array('min_length' => 4))
  111. ));
  112.  
  113. 自定義錯誤信息
  114. 'email' => new sfValidatorEmail(
  115. array(),
  116. array(
  117. 'required' => "Please enter email",
  118. 'invalid' => "Please enter a valid email address"
  119. )
  120. ),
  121. 'message' => new sfValidaorString(
  122. array('min_length' => 4),
  123. array(
  124. 'required' => "Please enter message",
  125. 'min_length' => "Please enter a longer message at least 4 char"
  126. )
  127. ),
  128.  
  129. 驗證兩次輸入的密碼
  130. $this->form = new sfForm();
  131. $this->form->setWidgets(array(
  132.   'login'     => new sfWidgetFormInputText(),
  133.   'password1' => new sfWidgetFormInputText(),
  134.   'password2' => new sfWidgetFormInputText()
  135. );
  136. $this->form->setValidators(array(
  137.   'login'     => new sfValidatorString(), // login is required
  138.   'password1' => new sfValidatorString(), // password1 is required
  139.   'password2' => new sfValidatorString(), // password2 is required
  140. ));
  141. $this->form->setPostValidators(new sfValidatorSchemaCompare('password1', '==', 'password2'));
  142.  
  143. 驗證下拉式選單中的資料是否存在於資料庫中
  144. $form->setValidator('section_id', new sfValidatorDoctrineChoice(array(
  145.   'model'  => 'Section',
  146.   'column' => 'name'
  147. )));
  148.  
  149. 驗證此用戶名是否已經存在
  150. $form->setValidator('nickname', new sfValidatorDoctrineUnique(array(
  151.   'model'  => 'User',
  152.   'column' => 'login'
  153. )));
  154.  
  155. CSRF 保護
  156. - 設置密碼
  157.   $form->addCSRFProtection('flkd445rvvrGV34G');
  158.  
  159. - settings.yml 中設置整個網站保護
  160.   all
  161.     .settings:
  162.       csrf_secret: ##…##
  163.       
  164. *** 最好是將 from 儲存為 lib/form/ContactForm.class.php
  165. *** 這樣就可以簡單的讀取和改變內裡的資料 (如: setWidget / setValidator)
  166.  
  167. 生成表單
  168. php symfony doctrine:build-forms
第 11 章
  1. 調用 mailer
  2. - $mailer = sfContext::getInstance()->getMailer();
  3.  
  4. 發送郵件
  5. $this->getMailer()->composeAndSend(from_email, to_email, subject, content);
  6.  
  7. 發送群組電郵
  8. $to_email = array(
  9. 'email' => 'name',
  10. 'email' => 'name',
  11. );
  12. $this->getMailer()->composeAndSend(from_email, $to_email, subject, content);
  13.  
  14. 建立消息對象,發送郵件
  15. $message = $this->getMailer()
  16. ->compose(from_email, to_email, subject, content)
  17. ->attach(Swift_Attachment::fromPath('/path/to/a/file.zip'));
  18. $this->getMailer()->send($message);
  19.  
  20. 利用視圖
  21. $message->setBody($this->getPartial('partial_name', $arguments));
  22.  
  23. 配置文件
  24. factories.yml
  25.  
  26. 改變下次發送情況為即刻發送
  27. $this->getMailer()->sendNextImmediately()->send($message);
  28.  
  29. transport 的 class 類別
  30. - Swift_SmtpTransport
  31. - Swift_SendmailTransport
  32. - Swift_MailTransport
  33. * http://swiftmailer.org/docs/transport-types
  34.  
  35. 使用 Gmail
  36. transport:
  37.   class: Swift_SmtpTransport
  38.   param:
  39.     host:       smtp.gmail.com
  40.     port:       465
  41.     encryption: ssl
  42.     username:   your_gmail_username_goes_here
  43.     password:   your_gmail_password_goes_here
第 12 章
  1. 清除緩存
  2. $cacheManager = sfContext::getInstance()->getViewCacheManager();
  3. $cacheManager->remove('publication/list');
  4.  
  5. 取得 template 路徑
  6. sfConfig::get(’sf_template_cache_dir’)
  7.  
  8. 後台不能夠刪除前台的緩存
  9. $frontend_cache_dir = sfConfig::get('sf_cache_dir').DIRECTORY_SEPARATOR.'frontend'. DIRECTORY_SEPARATOR.sfConfig::get('sf_environment').DIRECTORY_SEPARATOR.'template';
  10. $cache = new sfFileCache(array('cache_dir' => $frontend_cache_dir)); // 使用前台factories.yml文件中相同的设置。
  11. $cache->removePattern('user/show?id=12');
  12.  
  13. 如果是 memcache 的情況
  14. $cache = new sfMemcacheCache(array('prefix' => 'frontend'));
  15. $cache->removePattern('user/show?id=12');
第 13 章
  1. 設置語系
  2. frontend/config/i18n.yml
  3. all:
  4.   default_culture: fr_FR
  5.  
  6. $this->getUser()->setCulture('en_US');
  7. $this->getUser()->getCulture();
  8.  
  9. $sf_user->setCulture('en_US');
  10.  
  11. 取得預設語系
  12. $languages = $request->getLanguages();
  13.  
  14. 取得結構化時間
  15. list($d, $m, $y) = $this->getContext()->getI18N()->getDateForCulture($date, $user_culture);
  16.  
  17. 按模板分割
  18. - modules/[my_module]/i18n/message.xx.xml
  19.   - php symfony i18n:extract frontend en
  20.  
  21. 在原字典上追加字符串
  22. php symfony i18n:extract --auto-save frontend en
  23.  
  24. 自動刪除舊的字符串
  25. php symfony i18n:extract --auto-save --auto-delete frontend en
  26.  
  27. 拆分較好方法
  28. < ?php echo __('There are %1% persons logged', array('%1%' => count_logged())) ?>
  29.  
  30. 在 action 中呼叫
  31. $this->getContext()->getI18N()->__($text, $args, 'messages');
第 14 章
  1. 初始化管理界面
  2. php symfony propel:generate-admin backend BlogArticle --module=article
  3.  
  4. 如沒看見圖片
  5. php symfony plugin:publish-assets

轉錄 - 你有去華爾街的資格麼

很多天过去,当我回想起来这噩梦般的6个小时,都依然觉得神情恍惚,无法思考。

一个很平凡的下午,收到Morgan Stanley邮件说,Quantitative Finance Program希望你
来跟我们Securitized Product Group的一个Manager进行一个on-site interview.

于是我来美的处女面就华丽地献给了华尔街最quant的一个公司的最quant的一个组的一个
大boss。

其实on site一面的时候,与Managing director相谈甚欢,给MD发follow up邮件,回信热
情洋溢,最后说I look forward to coming back to you with next steps.

回想起来,MD的问题确实是很简单的,只问到了fixed income和比较基础的stochastic
calculus, 基本上知道伊藤引理和Black Scholes的推导足以。其余的便是聊mortgage
back secuirity的modeling,一直是我在问,他在讲。

我当时怎么知道这是噩梦的开始。

几天后收到HR邮件,7个背靠背的interview. 从associate到vice president再到
executive director.


第一个interviewer是个UIUC的物理学PhD。我特意找美国人打听了一下,答曰UIUC的
graduate school极强,绝对属于顶尖级别。

第一个问题什么叫securitilizaton(证券化),答曰it is the process of combining
loans with similar characteristics for collateral to issue debt.

PhD GG点头。我暗自庆幸自己背了定义来的。

接着他从我简历上的第一个项目问到最后一个项目。从data的source, distribution,
sampling,bias,问到regression method, model assumption,why this assumption,
why this indicator, why not other indicator, 再到conclusion, how to interpret,
how to explain,最后问我认为model应该如何改进,各种细节,精确到汗毛。其中不断
地质疑模型的数据,假设,建模,结论,我便把当年简大人搪塞我的各 种理由一一搬出来
搪塞他。总而言之,那些模型在他眼中仿佛都是玩具·····

从我过去工作中问不到任何有营养的内容的PhD GG又转而问我高中物理竞赛考什么。于是
连力学光学都不知道要怎么说的我,手舞足蹈语无伦次地解释了半天,PhD GG疑惑地看着
我,仿佛见到外星人。

最后GG拿出一张纸,两道概率题,我挣扎了很久很久很久,做出来一道。然后时间到。GG
收走我的卷子,说,下一个interviewer马上到。


第二个interviewer是个斯坦福PhD,长得,就是,一看便是天才+神童的长相。你们明白我
意思么····就是,我看到他的瞬间,就觉得,我跟他的智商水平,根本就不在一个数
量级上·······

头两个问题很简单,数学问题,只是我在美式度量衡上犯了很大的错误。

第三个问题VaR,算法,Conditional VaR, 然后给分布给我,要我算,我积分积了半天,
积错无数次。顺带着问我标准正态分布各种quantile的值,不偏离一个标准差的概率是多
少。完全不记得这些数字的我,只能暗暗痛恨我怎么就不是个人脑计算器····

第四个问题半物理半数学,大约是一个人在一个动态的平台上以某种随机的形式射箭,问
落点的概率分布。

一上来,完全没想法。在斯校男的提示下,找到了累积概率分布,然后就是各种恐怖的带
arctan(1/x)的积分求导,我历经若干次换元,若干次隐函数求导之后终于得到答案。

但是这个函数竟然不收敛。竟然不收敛啊!!!

斯校男很鄙视地看着我,说,我给你5分钟,你搞清楚这是怎么回事。

第五分钟的时候他抬起头说,想清楚没,我说,tanx在实数轴不连续,要分段定义。

他说好吧我相信你知道怎么做。其实我根本不知道。

然后时间到了。



第三个人是哥大Master,唯一的一个Master,我心里暗暗想着,救星啊,人民的大救星。

于是最惨烈的过程开始了。

在长达45分钟的时间里,我完全不能答对任何一个问题。

他不停地问各种衍生品的期望收益率,我一直用错误的方法给他答案,于是,不论我说什
么,他都很淡定地回一句,this is not true,然后举一个反例。

后来我情绪完全崩溃了,直接回答不知道,他再说一次this is not true我便万劫不复。

最后我终于明白了他是想要我算beta····which,我连securities的公式都没记清楚。

我内心顿时无限委屈,要我算这个,早点说啊,我直接说不会就完了····大家都这么
忙,干嘛互相浪费时间·······

大约是为了安抚我,哥大GG问了一个很简单的C++的stack和heap的问题。然后说,祝你好
运,翩然而去。

 
第四个interview是哈佛男A。

哈佛男的问题大多不难,但是一直拿我当计算器用。

比如30年的zero coupon bond, 2.5% risk free rate,价格等于多少。我说100除以1.02
5的30次方啊。哈佛男愣了一下,说,等于多少?

我震惊了一下,心想从来不知道这个要心算的。挣扎了半天,将分母泰勒展开,再求商,
给了一个数。

哈佛男说,you pay too much for it.

我说,大概是因为我泰勒展开只取了一阶····

后来我才知道,貌似有个牛叉闪闪的rule of 72可以简单心算bond price. 可是,21世纪
了,我怎么知道这些东西会要人算···

他又问各种coupon bond的price,各种等比数列求和,各种多项式展开,仿佛回到高中。

然后他开始问宏观经济,美联储的quantitative easing, 原因,机制,结果,美国的
enterpreneourship,美国对其他国家的影响等等。

后来他问了一个很奇怪的问题,于是我愣了大约5秒钟。他说,你学过宏观经济么?我说,
学过···他说,他们没教你怎么样对经济形成一个观点么?我说,这个靠自己去follow
market….

他说,你这个program到底教什么呢?

我努力listing…

他打断,说,你在国内有很好的工作,或者说,你在中国什么都有,你来读这个项目是为
了什么?就是为了一个美国的身份和机会是么?

我如遭雷击,半晌无语。

对于why finance, why CMU, why investment banking这类的问题,我排练过一百遍早已
烂熟于胸。可是当他用这样的形式抛出这个问题,我忽然觉得心里狠狠地痛了一下。


很长很长的时间里,我都一直无法抛下过去。对于我所离开的,所放弃的那些,始终都觉
得无法言语的伤痛。可是我什么都不能说。

自己选的路,跪着走也要走完,没有资格抱怨,也没有资格怀念。

可是他真的很准确地戳到了我的痛点。


从那个问题之后,我一直心情很低落。我放弃了defending myself。他说,我刚刚面了两
个人,一个是爱尔兰的第一名,一个是印度的99.95%quantile,你觉得他们比较
impressive,还是你比较impressive?

我说他们比较impressive。

他说你还有问题么,我说没有。


他说,你可以下去买午饭,下一个interviewer 15分钟后到。
浑浑噩噩地走出Morgan Stanley华丽的大厅,走在冰冷的纽约街头我突然就很想哭。

我真的很想家。我真的很想你。

我放弃的这一切换来一个多么讽刺的问题啊。


我匆匆塞了些食物,努力努力地调整心情。当时我还不知道,这一上午只是噩梦的开始。

第六个interviewer背景未知,只知道是computer science出身。

各种equity pricing,option pricing,心算black scholes的简化版本,心算开平方,心
算lg4000000000,各种C++

我心不在焉的,算得很慢很慢。

code不会写,只说了大概想法。大概是C++怎么处理excel sheet里的数据,which,完全没
见过。

心算开平方没算对,他说,you are close, but not right。不过时间到了,我同事已经
在等了。


第6个便是传说中的哈佛男B,国际数学奥林匹克竞赛美国队成员,又是一个一看便知道智
商高过我们普通人数量级的外貌。

先是最大化期望的问题,算错了,经提示改正。

他说,我问你一个简单的finance问题吧

然后最crazy的部分来了

我完全没听懂。

又问了一遍

依然没听懂

问了无数问题后,终于明白他是要我给一个delta neutral, long gamma的portfolio定价
,如果underlying price服从以下分布

a)带跳的几何布朗运动

b)带time-variant的飘移项的几何布朗运动

which, 我根本没想法。

然后是两个C++ code题。

第一题居然会写。写完了他说,你这个算法可以,但是memory不够efficient,重写。大抵
是我不应该用可变长度的数列。于是我和他为了在一个for循环里是先算甲还是先算乙的问
题纠结了半天,结果我错了。

好不容易写完了code,他端详良久,然后说,你这个不行,然后给我画流程图证明为什么
不行。彼时我大脑已经完全空白,无法思考,不论他说什么,我都是茫然地看着。最后他
说,不对,这个可行。我松了一口气。

第二题写C++ code矩阵求解,即解一n元一次方程,which, 我连想法都没有。

他看他的材料去了,我在草稿纸上画画。

过了5分钟他过来看我的纸,我bull*****了几行代码,他说,恩,我大概知道你什么意思了
·····你想用两个for loop迭代求解….

我大惊,这都可以?


第七个interviewer已经来了,于是代码题匆匆夭折。韩国GG。

这是直接带着卷子来的,第一题binonimal tree求option price,对了。

第二题是带相关性的联合正态分布的两个随机变量的条件概率分布问题。我很纠结地开始
写双重积分,韩国GG说,你这样会算死的。

我无想法,他说,找线性变换。

我忽然想到的确是有公式消除相关性的,不记得了,只能从头推起。

找到新的变量,依然不知道怎么算概率。

GG无奈地提示说,换坐标系啊。

我疑惑状。

再提示说,找面积啊。

我赶紧画图,发现是一个无穷比无穷的面积。

我想了半天,用一个正方形框住,然后算面积比。

GG说,错了错了,坐标系上的点不是均匀分布的,靠近原点的点概率大,你不能用正方形
····根据原点对称性,你要用扇形····

我作恍然大悟状,然后想他大概在心里鄙视我一千遍了吧。

GG站起来,说,我有个会,不能回答你的问题了,你回家去吧。

于是,我第二次恍恍惚惚地走出了Morgan Stanley的大门。

下午4点50分的纽约,天已经全黑了。衣着单薄的我只觉得彻骨的冷,彻骨的冷。时代广场
上灯火通明人潮熙攘,让我仿佛有种错觉,像是回到了那些独自走过光谷广场的日子。

当时的我,还是会愿意时常看看那些华丽的灯红酒绿的世界啊。

我不想回头看。我还要赶回downtown。还有50分钟,fixed income课就要开始了。

坐在纽约百年历史的破旧的地铁中,我看着车窗中自己狼狈不堪的倒影,努力告诉自己不
要哭。在这个压抑到死的城市中,我无法呼吸,无法思考。我头脑一片惨淡的空白。

我真的很想就这样一直发呆发下去。

直到,

” Next stop, Wall Street.”
本文来自: 人大经济论坛 真实世界的经济学 版,详细出处参考:http://bbs.pinggu.org/viewthread.php?tid=980772&page=1