A Gentle Introduction to symfony 筆記

參考來源:http://www.symfony-project.org/gentle-introduction/1_4/

這篇筆記未提及安全,請至:http://www.symfony-project.org/gentle-introduction/1_4/en/06-Inside-the-Controller-Layer 查看 Action Security

看完還不懂怎麼建 project 沒關係,因為我也沒完全透澈,所以寫的筆記會丟三落四

template

  1. 在 action 中用:

    $this->abc = 'ooxx';

在 template 就可以使用:

echo $abc;
  1. $sf_request, $sf_params, $sf_response, and $sf_user 是 template 內建變數可以直接在 template 用,例如取得 GET:

    $sf_params->get('name');
    $sf_params->get('name', 'John Doe'); # 沒有 name 時,使用 'John Doe' 當預設值
  2. url_for(‘content/update’)

  3. link_to(‘I never say my name’, ‘content/update?name=anonymous’),以及可以這樣寫:

    // 用 associative array 寫
    <?php echo link_to('I never say my name', 'content/update?name=anonymous',
      array(
        'class'    => 'special_link',
        'confirm'  => 'Are you sure?',
        'absolute' => true
    )) ?>
    
    // 用字串寫
    <?php echo link_to('I never say my name', 'content/update?name=anonymous',
        'class=special_link confirm=Are you sure? absolute=true') ?>
    
    // 輸出
    <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>
  4. 使用 user session 資料:

    $sf_user->getAttribute('nickname')
  5. Flash:

    echo $sf_user->getFlash(‘notice’);

補充,需在 action 做的東西是:

$this->getUser()->setFlash('notice', $value);
$value = $this->getUser()->getFlash('notice');

helper

Template Shortcuts:

// Long version
<?php echo $sf_request->getParameter('total') ?>

// Shorter version
<?php echo $sf_params->get('total') ?>

// Equivalent to the following action code
echo $request->getParameter('total')

Partials

  1. template:

    <?php include_partial('mypartial1') ?>
    <?php include_partial('global/mypartial3') ?>
    <?php include_partial('mypartial', array('mytotal' => $total)) ?>
  2. action:

    public function executeFoo()
    {
      // do things
      $this->foo = 1234;
      $this->bar = 4567;
    
      return $this->renderPartial('mymodule/mypartial');
    }

or:

return $this->renderPartial('mymodule/mypartial', array('foo' => $this->foo));

action

  1. 取得 request 資料:

    $request->getParameter('name');
  2. 範例:

    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         : The controller object (->getController())
sfRequest            : The request object (->getRequest())
sfResponse           : The response object (->getResponse())
sfUser               : The user session object (->getUser())
sfRouting            : The routing object (->getRouting())
sfMailer             : The mailer object (->getMailer())
sfI18N               : The internationalization object (->getI18N())
sfLogger             : The logger object (->getLogger())
sfDatabaseConnection : The database connection (->getDatabaseConnection())
  1. 終結 action:

    return sfView::SUCCESS; # symfony 會直接去 <action_name>Success.php
    return sfView::ERROR; # symfony 會直接去 <action_name>Error.php
    return 'MyResult'; # symfony 會去找 <action_name>MyResult.php;
    return sfView::NONE; # 沒有 template 時就用這個

其中針對 sfView::NONE 說明:

public function executeIndex()
{
  $this->getResponse()->setContent("<html><body>Hello, World!</body></html>");

  return sfView::NONE;
}

// 上面的函式跟這個一樣結果
public function executeIndex()
{
  return $this->renderText("<html><body>Hello, World!</body></html>");
}

這是另一個,return sfView::HEADER_ONLY;
public function executeRefresh()
{
  $output = '<"title","My basic letter"],["name","Mr Brown">';
  $this->getResponse()->setHttpHeader("X-JSON", '('.$output.')');

  return sfView::HEADER_ONLY;
}
  1. 使用不同 template:

    $this->setTemplate('myCustomTemplate');
  2. 頁面切換:

    # 直接切到某 action
    $this->forward('otherModule', 'index');
    
    # 直接跳轉
    $this->redirect('otherModule/index');
    $this->redirect('http://www.google.com/');
    
    # 切到 404 頁面
    $this->forward404();
    
    # forward404If
    public function executeShow(sfWebRequest $request)
    {
      $article = Doctrine::getTable('Article')->find($request->getParameter('id'));
      $this->forward404If(!$article);
    }
    
    # forward404Unless
    public function executeShow(sfWebRequest $request)
    {
      $article = Doctrine::getTable('Article')->find($request->getParameter('id'));
      $this->forward404Unless($article);
    }
  3. 特殊函式:

    # 每個 action 前執行
    public function preExecute() {}
    
    # 每個 action 後執行
    public function postExecute() {}
    
    # 自定 action,不會被 url request 到,但還是使用 private/protected 來宣告
    protected function myCustomMethod() {}
  4. session:

    # set to user session
    $this->getUser()->setAttribute('nickname', $nickname);
    
    # get from user session
    $nickname = $this->getUser()->getAttribute('nickname', 'Anonymous Coward');
    
    # remove from user session
    $this->getUser()->getAttributeHolder()->remove('nickname');
    
    # clear user session
    $this->getUser()->getAttributeHolder()->clear();

request

Name Function Sample Output
Request Information    
isMethod($method) Is it a post or a get? true or false
getMethod() Request method name ‘POST’
getHttpHeader(‘Server’) Value of a given HTTP header ‘Apache/2.0.59 (Unix) DAV/2 PHP/5.1.6’
getCookie(‘foo’) Value of a named cookie ‘bar’
isXmlHttpRequest()* Is it an Ajax request? true
isSecure() Is it an SSL request? true
Request Parameters    
hasParameter(‘foo’) Is a parameter present in the request? true
getParameter(‘foo’) Value of a named parameter ‘bar’
getParameterHolder()->getAll() Array of all request parameters  
URI-Related Information    
getUri() Full URI http://localhost/frontend_dev.php/mymodule/myaction
getPathInfo() Path info ‘/mymodule/myaction’
getReferer()** Referrer http://localhost/frontend_dev.php/
getHost() Host name ‘localhost’
getScriptName() Front controller path and name ‘frontend_dev.php’
Client Browser Information    
getLanguages() Array of accepted languages Array( [0] => fr [1] => fr_FR [2] => en_US [3] => en )
getCharsets() Array of accepted charsets Array( [0] => ISO-8859-1 [1] => UTF-8 [2] => * )
getAcceptableContentTypes() Array of accepted content types Array( [0] => text/xml [1] => text/html

設定檔

在往下看之前,你要記住,在多數環境下,所有設定檔預設值你並不需要修改

專案 config 目錄:

config
├── ProjectConfiguration.class.php # 特別留意這個程式,有時需要修改
├── databases.yml
├── doctrine
│   └── schema.yml
├── properties.ini
└── rsync_exclude.txt

web/index.php:

require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');

$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', false); # 執行 frontend app, 是 production 環境, debug == false;
sfContext::createInstance($configuration)->dispatch();

# 特別關注
$configuration->getRootDir()
$configuration->getApplication()
$configuration->getEnvironment()
$configuration->isDebug()

apps/frontend/config:

.
├── app.yml
├── cache.yml
├── factories.yml
├── filters.yml
├── frontendConfiguration.class.php
├── routing.yml
├── security.yml
├── settings.yml
└── view.yml

model

config/doctrine/schema.yml:

Article:
  actAs: [Timestampable]
  tableName: blog_article
  columns:
    id:
      type: integer
      primary: true
      autoincrement: true
    title:   string(255)
    content: clob

Comment:
  actAs: [Timestampable]
  tableName: blog_comment
  columns:
    id:
      type: integer
      primary: true
      autoincrement: true
    article_id: integer
    author: string(255)
    content: clob
  relations:
    Article:
      onDelete: CASCADE
      foreignAlias: Comments

然後就可以使用:

$ ./symfony doctrine:build-model

產出檔案:

>> doctrine  generating model classes
>> file+     /var/tmp/doctrine_schema_ooxx.yml
>> tokens    <your_project_path>lib/model/doctrine/ArticleTable.class.php
>> tokens    <your_project_path>lib/model/doctrine/Article.class.php
>> tokens    <your_project_path>lib/model/doctrine/CommentTable.class.php
>> tokens    <your_project_path>lib/model/doctrine/Comment.class.php
>> tokens    <your_project_path>lib/model/doctrine/base/BaseArticle.class.php
>> tokens    <your_project_path>lib/model/doctrine/base/BaseComment.class.php
>> autoload  Resetting application autoloaders
>> file-     <your_project_path>/cache/frontend/prod/config/config_autoload.yml.php

其他要細讀:http://www.symfony-project.org/gentle-introduction/1_4/en/08-Inside-the-Model-Layer-Doctrine

補充:產出 sql file,再自行匯入:

$./symfony doctrine:build-sql

如果要從既有 db 產出 schema.yml:

$./symfony doctrine:build-schema

Admin Generator

建立後台 app:

./symfony generate:app backend
./symfony doctrine:generate-admin backend Article --module=article

繼續閱讀

因為東西真的很多,所以要繼續讀完後半部才能繼續分享...

內容目錄

上一個主題

Symfony 1.4 簡易 Hello, World

下一個主題

Yii Framework 筆記

本頁