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

沒有留言:

張貼留言