Moya's Blog

PHP

PHP Programming

PHP 程式設計相關文獻整理

使用 Symfony 的 Session 控制機制

5 months, 1 week ago in by MoyaTseng
Symfony 支援了數種常見的 Session 控制機制,包括

  • sfSessionStorage
  • sfMySQLSessionStorage
  • sfPostgreSQLSessionStorage
  • sfMemcacheSessionStorage

個人不覺得用 database 當 session 的 backend storage 會是個好主意,很容易會卡在 database 的 performance 上。當然使用 PHP 內建的單機版本的也沒有什麼擴充性可言,所以也不考慮。

個人比較推薦採用外掛 Plugin 所支援 memcached 或是 memcachedb 的機制,會比內建的三種機制都來得適當一些。在 Performance 上會有很大的改進,而且,擴充性也會比較好。

參考文件

與 Session 相關的設定

Session 儲存體的機制設定

  1. 檔案:apps/[app-name]/config/factories.yml
  2. 內容:
    all:
      storage:
        class: sfSessionStorage
        param:
          session_name: [default= symfony]
          database: 
          db_id_col: [default= sess_id]
          db_data_col: [default= sess_data]
          db_time_col: [default= sess_time]
    
  3. 可以用的 storage class 包括
    1. sfSessionStorage
    2. sfMySQLSessionStorage
    3. sfPostgreSQLSessionStorage
    4. sfMemcacheSessionStorage (非 symfony 內建提供機制,需要加裝 sfAdvMemcachedCache 套件)

用途:設定 timeout 的時間

  1. 檔案:apps/[app-name]/config/settings.yml
  2. 內容:
    default:
      .settings:
        timeout:     1800           # Session lifetime in seconds
    

支援的 Session 儲存體

  1. sfSessionStorage
    • 標準 PHP Session
  2. sfMySQLSessionStorage
    • 使用 MySQL Session Storage
    • 資料庫相關參數的設定,設定在 factories.yml 的 param 項目:
      設定參數 預設值 說明
      db_table The database table in which session data will be stored.
      database 目前用的資料庫 The database connection to use (see databases.yml)
      db_id_col sess_id The database column in which the session id will be stored.
      db_data_col sess_data The database column in which the session data will be stored.
      db_time_col sess_time The database column in which the session timestamp will be stored.
      session_name symfony The name of the session.
  3. sfPDOSessionStorage
    • 採用 PDO Database 的 Session Storage
    • 參數設定與 sfMySQLSessionStorage 相同
  4. sfPostgreSQLSessionStorage
    • 採用 PostgreSQL Database 的 Session Storage
    • 參數設定與 sfMySQLSessionStorage 相同
  5. sfMemcacheSessionStorage
    • 需要先安裝 pecl-memcache 套件
      cd /usr/ports/databases/pecl-memcache
      make all install clean
      
    • 需要安裝 sfAdvMemcachedCache 套件
    • 下載 sfAdvMemcachedCache.zip External link mark 檔案
    • 解開後放在 /usr/local/share/pear/symfony/storage 目錄下

存取控制

存取設定

  1. 檔案:apps/[app-name]/modules/[module-name]/config/security.yml
  2. 內容:
    read:
      is_secure:   off       # All users can request the read action
    
    update:
      is_secure:   on        # The update action is only for authenticated users
    
    delete:
      is_secure:   on        # Only for authenticated users
      credentials: admin     # With the admin credential
    
    all:
      is_secure:  off        # off is the default value anyway
    

預設行為定義

  1. 檔案:apps/[app-name]/config/settings.yml
  2. 內容:
    all:
      .actions:
        login_module:           default
        login_action:           login
    
        secure_module:          default
        secure_action:          secure
    
    … reply

讓 Symfony-1.0 支援 Propel-1.3

5 months, 1 week ago in by MoyaTseng
Symfony-1.0 因為採用的是 Propel-1.2,預設只支援 Creole,不過這個 database framework 長期以來飽受爭議的問題在於它的速度太慢了,所以在 PHP 把 PDO 納入標準支援程序當中之後,Symfony-1.1 就正式採用支援 PDO 的 Propel-1.3 了。

只不過這種好處要等到 Symfony-1.1 完成後才能夠使用,總是有點美中不足。雖然也可以直接使用 Symfony-1.1 來開發網站,但畢竟到目前為止,Symfony-1.1 還是 beta 的版本 RC2 而已,要用做正式的網站還是不是那麼的適當。所以這個時候 sfPropel13Plugin 就派上用場了。

Document Reference

  1. The sfPropel13 Plugin External link mark

Install sfPropel13Plugin

  1. cd /usr/local/share/pear/symfony/plugins
  2. svn co http://svn.symfony-project.com/plugins/sfPropel13Plugin/ sfPropel13Plugin

目的

  1. 採用 sfPropel13Plugin 為基礎架構
  2. Propel-1.3 採用的是 PHP 內建的 PDO,比 symfony 1.0 目前所用的 Creole 有更好的效能,而 PDO 要到 symfony 1.1 才會支援的。

參考文件

  1. Upgrading to Propel 1.3 External link mark
  2. using propel 1.3 External link mark
  3. sfPropel13Plugin - The power of Propel 1.3 External link mark
  4. The sfPropel13 Plugin External link mark

初始化專案

  1. cd /usr/local/www/[project name]
  2. symfony init-project
  3. symfony init-app frontend

安裝需要的套件

  1. sfPropel13Plguin
    cd ~[project name home path]/plugins
    mkdir sfPropel13Plugin
    svn co http://svn.symfony-project.com/plugins/sfPropel13Plugin/ sfPropel13Plugin
    

資料庫的相關設定

  • 以 sfPropel13Plugin 作為 database 的 backend

propel.ini 設定

  1. 檔案: [project name]/config/propel.ini
  2. 相關的內容設定:
    propel.project             = [project name]
    propel.database            = pgsql
    propel.database.user       = [database user]
    propel.database.password   = [database password]
    propel.database.createUrl  = pgsql://[database user]:[database password]@[database hostname]/[database name]
    propel.database.url        = pgsql:dbname=[database name];host=[database hostname]
    propel.database.creole.url = pgsql://[database user]:[database password]@[database hostname]/[database name]
    
    ; builder settings
    propel.builder.peer.class      = plugins.sfPropel13Plugin.lib.propel.builder.SfPeerBuilder
    propel.builder.object.class    = plugins.sfPropel13Plugin.lib.propel.builder.SfObjectBuilder
    

databases.yml 設定

  1. 檔案: [project name]/config/databases.yml
  2. 相關的內容設定:
    all:
      propel:
        class:              sfPropel13Database
        param:
          phptype:          pgsql
          dsn:              pgsql:dbname=[database name];host=[database hostname]
          database:         [database name]
          username:         [database user]
          password:         [database password]
          instance-pooling: true
    

重建專案

  1. 清除既有的專案 cache
    symfony cc
    
  2. 依據 sfPropel13Plguin 建立 database backend 相關 model
    symfony propel-13-build-all
    

sfPropel13Plugin 所支援的 model functions

  • generate propel model and sql and initialize database
    propel-13-build-all  
    
  • generate propel model and sql and initialize database, and load data
    propel-13-build-all-load
    
  • create classes for current model
    propel-13-build-model
    
  • create schema.xml from existing database
    propel-13-build-schema
    
  • create sql for current model
    propel-13-build-sql
    
  • create schema.yml from schema.xml
    propel-13-convert-xml-schema
    
  • create schema.xml from schema.yml
    propel-13-convert-yml-schema
    
  • dump data to fixtures directory
    propel-13-dump-data
    
  • generate a new propel CRUD module
    propel-13-generate-crud
    
  • initialize a new propel admin module
    propel-13-init-admin
    
  • initialize a new propel CRUD module
    propel-13-init-crud
    
  • insert sql for current model
    propel-13-insert-sql
    
  • load data from fixtures directory
    propel-13-load-data
    

… reply

利用 Symfony sfGuardPlugin 建立帳號系統

5 months, 1 week ago in by MoyaTseng
網路上的文件的說明都不是很完整,所以花了滿多的時間才搞定基本的功能瞭解,事實上還不是真的非常清楚整個架構,或許未來有機會進行進一步的深入瞭解,到時候可以再提供更深入的使用說明。

其實至少還要支援 sfCaptchaPlugin 的支援才是真的完成了符合現今流行的會員網站的最基本架構。那個部分等我把 sfGuardPlugin 瞭解得更透徹之後再提供如何加上那個功能的說明吧。

目的

  1. 採用 sfPropel13Plugin 為基礎架構
  2. 支援 sfGuardPlugin 為登入與認證管控機制

參考文件

  1. Howto do a Captcha in Symfony - with Plugins External link mark
  2. sfGuard plugin - extra documentation External link mark
  3. sfGuardPluginPlus External link mark
  4. How To Extend Propel Plugin Model External link mark
  5. How to override sfGuardUser External link mark

初始化專案

  1. cd /usr/local/www/[project name]
  2. symfony init-project
  3. symfony init-app frontend
  4. symfony init-app backend

安裝需要的套件

  1. sfGuardPlugin
    symfony plugin-install http://plugins.symfony-project.com/sfGuardPlugin 
    
  2. sfPropel13Plguin
    cd ~[project name home path]/plugins
    mkdir sfPropel13Plugin
    svn co http://svn.symfony-project.com/plugins/sfPropel13Plugin/ sfPropel13Plugin
    

為支援 sfProepl13Plugin 進行 sfGuardPlugin patch

  1. plugins/sfGuardPlugin/modules/sfGuardGroup/config/generator.yml
    --- plugins/sfGuardPlugin/modules/sfGuardGroup/config/generator.yml   2007-11-03 13:31:20.000000000 +0000
    +++ plugins/sfGuardPlugin/modules/sfGuardGroup/config/generator.yml   2007-11-03 13:39:11.000000000 +0000
    @@ -1,5 +1,5 @@
     generator:
    -  class:              sfPropelAdminGenerator
    +  class:              sfPropel13AdminGenerator
       param:
         model_class:      sfGuardGroup
         theme:            default
    
  2. plugins/sfGuardPlugin/modules/sfGuardPermission/config/generator.yml
    --- plugins/sfGuardPlugin/modules/sfGuardPermission/config/generator.yml   2007-11-03 13:42:07.000000000 +0000
    +++ plugins/sfGuardPlugin/modules/sfGuardPermission/config/generator.yml   2007-11-03 13:42:48.000000000 +0000
    @@ -1,5 +1,5 @@
     generator:
    -  class:              sfPropelAdminGenerator
    +  class:              sfPropel13AdminGenerator
       param:
         model_class:      sfGuardPermission
         theme:            default
    
  3. plugins/sfGuardPlugin/modules/sfGuardUser/config/generator.yml
    --- plugins/sfGuardPlugin/modules/sfGuardUser/config/generator.yml   2007-11-03 13:25:46.000000000 +0000
    +++ plugins/sfGuardPlugin/modules/sfGuardUser/config/generator.yml   2007-11-03 14:56:52.000000000 +0000
    @@ -1,5 +1,5 @@
     generator:
    -  class:              sfPropelAdminGenerator
    +  class:              sfPropel13AdminGenerator
       param:
         model_class:      sfGuardUser
         theme:            default
    
  4. ./plugins/sfGuardPlugin/lib/model/plugin/PluginsfGuardUser.php
    *** ./plugins/sfGuardPlugin/lib/model/plugin/PluginsfGuardUser.php-orig 2008-06-12 17:18:59.000000000 +0800
    --- ./plugins/sfGuardPlugin/lib/model/plugin/PluginsfGuardUser.php      2008-06-12 17:19:54.000000000 +0800
    ***************
    *** 263,269 ****
          $this->allPermissions = null;
        }
      
    !   public function delete($con = null)
        {
          // delete profile if available
          try
    --- 263,269 ----
          $this->allPermissions = null;
        }
      
    !   public function delete(PropelPDO $con = null)
        {
          // delete profile if available
          try
    
  5. plugins/sfGuardPlugin/lib/model/plugin/PluginsfGuardUserGroup.php
    *** ./plugins/sfGuardPlugin/lib/model/plugin/PluginsfGuardUserGroup.php-orig   2008-06-12 17:14:01.000000000 +0800
    --- ./plugins/sfGuardPlugin/lib/model/plugin/PluginsfGuardUserGroup.php 2008-06-12 17:14:19.000000000 +0800
    ***************
    *** 17,23 ****
       */
      class PluginsfGuardUserGroup extends BasesfGuardUserGroup
      {
    !   public function save($con = null)
        {
          parent::save($con);
      
    --- 17,23 ----
       */
      class PluginsfGuardUserGroup extends BasesfGuardUserGroup
      {
    !   public function save(PropelPDO $con = null)
        {
          parent::save($con);
      
    

資料庫的相關設定

  • 以 sfPropel13Plugin 作為 database 的 backend

propel.ini 設定

  1. 檔案: [project name]/config/propel.ini
  2. 相關的內容設定:
    propel.project             = [project name]
    propel.database            = pgsql
    propel.database.user       = [database user]
    propel.database.password   = [database password]
    propel.database.createUrl  = pgsql://[database user]:[database password]@[database hostname]/[database name]
    propel.database.url        = pgsql:dbname=[database name];host=[database hostname]
    propel.database.creole.url = pgsql://[database user]:[database password]@[database hostname]/[database name]
    
    ; builder settings
    propel.builder.peer.class      = plugins.sfPropel13Plugin.lib.propel.builder.SfPeerBuilder
    propel.builder.object.class    = plugins.sfPropel13Plugin.lib.propel.builder.SfObjectBuilder
    

databases.yml 設定

  1. 檔案: [project name]/config/databases.yml
  2. 相關的內容設定:
    all:
      propel:
        class:              sfPropel13Database
        param:
          phptype:          pgsql
          dsn:              pgsql:dbname=[database name];host=[database hostname]
          database:         [database name]
          username:         [database user]
          password:         [database password]
          instance-pooling: true
    

啟用預設的 sfGuardPlugin 介面功能

安裝的套件

  1. for the frontend-application
    1. sfGuardAuth
  2. for the backend-application
    1. sfGuardGroup
    2. sfGuardPermission
    3. sfGuardUser

新增的 Schema

  1. 檔名: [project name]/plugins/sfGuardPlugin/config/schema.yml
  2. 檔案內容:
    propel:
      _attributes:      { package: plugins.sfGuardPlugin.lib.model }
      
      sf_guard_group:
        _attributes:    { phpName: sfGuardGroup }
        id:             ~
        name:           { type: varchar, size: 255, required: true, index: unique }
        description:    { type: longvarchar }
      
      sf_guard_permission:
        _attributes:    { phpName: sfGuardPermission }
        id:             ~
        name:           { type: varchar, size: 255, required: true, index: unique }
        description:    { type: longvarchar }
      
      sf_guard_group_permission:
        _attributes:    { phpName: sfGuardGroupPermission }
        group_id:       { type: integer, primaryKey: true, required: true, foreignTable: sf_guard_group, foreignReference: id, onDelete: cascade }
        permission_id:  { type: integer, primaryKey: true, required: true, foreignTable: sf_guard_permission, foreignReference: id, onDelete: cascade }
      
      sf_guard_user:
        _attributes:    { phpName: sfGuardUser }
        id:             ~
        username:       { type: varchar, size: 128, required: true, index: unique }
        algorithm:      { type: varchar, size: 128, required: true, default: sha1 }
        salt:           { type: varchar, size: 128, required: true }
        password:       { type: varchar, size: 128, required: true }
        created_at:     ~
        last_login:     { type: timestamp }
        is_active:      { type: boolean, required: true, default: 1 }
        is_super_admin: { type: boolean, required: true, default: 0 }
      
      sf_guard_user_permission:
        _attributes:    { phpName: sfGuardUserPermission }
        user_id:        { type: integer, primaryKey: true, required: true, foreignTable: sf_guard_user, foreignReference: id, onDelete: cascade }
        permission_id:  { type: integer, primaryKey: true, required: true, foreignTable: sf_guard_permission, foreignReference: id, onDelete: cascade }
      
      sf_guard_user_group:
        _attributes:    { phpName: sfGuardUserGroup }
        user_id:        { type: integer, primaryKey: true, required: true, foreignTable: sf_guard_user, foreignReference: id, onDelete: cascade }
        group_id:       { type: integer, primaryKey: true, required: true, foreignTable: sf_guard_group, foreignReference: id, onDelete: cascade }
        
      sf_guard_remember_key:
        _attributes:    { phpName: sfGuardRememberKey }
        user_id:        { type: integer, primaryKey: true, required: true, foreignTable: sf_guard_user, foreignReference: id, onDelete: cascade }
        remember_key:   { type: varchar, size: 32 }
        ip_address:     { type: varchar, size: 50, primaryKey: true }
        created_at:     ~
    

啟用 sfGuardPlugin

  1. 先完成要啟用 sfGuardPlugin 相關 application 設定的更改
  2. 清除既有的 cache 檔案
    symfony cc
    
  3. 構建支援 sfGuardPlugin 的系統
    symfony propel-13-build-all
    

Module 啟用相關設定

  1. 啟用 Module
    1. 檔案: [project name]/apps/[frontend application]/config/settings.yml
    2. 內容:
      all:
        .settings:
          enabled_modules: [default, sfGuardAuth]
      
    3. 檔案: [project name]/apps/[backend application]/config/settings.yml
      all:
        .settings:
          enabled_modules: [default, sfGuardGroup, sfGuardUser, sfGuardPermission]
      
  2. 設定 Login 和 Secure 的 default action module
    1. 檔案: [project name]/apps/[frontend application]/config/settings.yml
    2. 內容:
      all:
        .actions:
          login_module:           sfGuardAuth
          login_action:           login
      
          secure_module:          sfGuardAuth
          secure_action:          secure
      
  3. 關閉 sfGuardAuth 的預設 routing 設定,取消預設的控制行為
    1. 檔案: [projace name]/apps/[frontend application]/config/app.yml
    2. 內容:
      # default values
      all:
        sf_guard_plugin:
          routes_register: false
      
  4. 設定 signin, signout, request_password 的相關 action module 及 url
    1. 檔案: [projace name]/apps/[frontend application]/config/routing.yml
    2. 這些設定要加在 default 之前,不然會被 default 攔截走內容:
      sf_guard_signin:
        url:   /login
        param: { module: sfGuardAuth, action: signin }
      
      sf_guard_signout:
        url:   /logout
        param: { module: sfGuardAuth, action: signout }
      
      sf_guard_password:
        url:   /request_password
        param: { module: sfGuardAuth, action: password }
      
  5. apps/frontend/config/security.yml
    default:
      is_secure: on 
    

程式調整,支援 sfGuardPlugin

  1. sfGuardPlugin 提供了一個 sfGuardSecurityUser,而 sfGuardSecurityUser 繼承自原來的 sfBasicSecurityUser,所以不會遺失任何 sfBasicSecurityUser 的功能。
  2. 修改 [project name]/apps/frontend/lib/myUser.class.php 把繼承來源的 class 調整為來自於 sfGuardPlugin 的版本
    class myUser extends sfGuardSecurityUser
    {
    }
    

管理介面

  1. URL: http://[hostname]/backend.php/sfGuardUser
  2. 依據提供的預設介面即可新增、刪除、查詢既有的使用者帳號

依據 sfGuardPlugin 擴充會員系統功能

增加自訂的 database schema

  1. 在 sfGuardPlugin 當中所支援的 database schema 相當有限,只包括了:
    1. username
    2. algorithm
    3. salt
    4. password
    5. created_at
    6. last_login
    7. is_active
    8. is_super_admin
  2. 預設 sfGuardUser 會參考 sfGuardUserProfile 來提供額外的 database schema 支援
  3. 要增加額外的 database schema,不需要修改 plugin 的 schema.yml 只要在自己專案的 schema.yml 增加相關的 datbase schema 即可
    1. 檔案: [project name]/config/schema.yml
    2. 內容:
      propel:
        sf_guard_career:
          _attributes: { phpName: sfGuardCareer }
          id:          ~
          name:        { type: varchar, size: 20 }
      
        sf_guard_career_i18n:
          _attributes: { phpName: sfGuardCareerI18n }
          id:          ~
          career_id:   { type: integer, required: true, primaryKey: true, foreignTable: sf_guard_career, foreignReference: id }
          culture:     { isCulture: true, type: varchar, size: 16, required: true, primaryKey: true }
          name_l10n:   { type: varchar, size: 20 }
      
        sf_guard_user_profile:
          _attributes:   { phpName: sfGuardUserProfile }
          id:            ~
          user_id:       { type: integer, foreignTable: sf_guard_user, foreignReference: id, required: true, onDelete: cascade }
          first_name:    { type: varchar, size: 20 }
          last_name:     { type: varchar, size: 20 }
          birthday:      { type: date }
          home_postcode: { type: varchar, size: 10 }
          home_address:  { type: varchar, size: 256 }
          home_country:  { type: varchar, size: 6 }
          home_region:   { type: varchar, size: 4 }
          home_phone:    { type: varchar, size: 10 }
          work_postcode: { type: varchar, size: 10 }
          work_address:  { type: varchar, size: 10 }
          work_country:  { type: varchar, size: 6 }
          work_region:   { type: varchar, size: 4 }
          work_phone:    { type: varchar, size: 10 }
          mobile1:       { type: varchar, size: 16 }
          mobile2:       { type: varchar, size: 16 }
          career:        { type: integer, foreignTable: sf_guard_career, foreignReference: id }
      
  4. 建立相關的資料庫與功能模組
    symfony cc
    symfony proepl-13-build-all
    
  5. 執行完以上的程序之後,資料庫中會建立 sf_guard_user_profile 這個資料庫
  6. 也會同時建立一下的 modules libraries
    1. [project name]/lib/model/sfGuardUserProfilePeer.php
    2. [project name]/lib/model/sfGuardUserProfile.php
    3. [project name]/lib/model/map/sfGuardUserProfileMapBuilder.php
    4. [project name]/lib/model/om/BasesfGuardUserProfile.php
    5. [project name]/lib/model/om/BasesfGuardUserProfilePeer.php
  7. 預設的資料
    1. 預設的資料內容, 檔案: [my project]/data/fixtures/sfGuardProfile.data
      sfGuardCareer: 
        sfGuardCareer_1: 
          name: engineer
      sfGuardCareerI18n: 
        sfGuardCareerI18n_1_1_en: 
          name_l10n: Engineer
      
    2. 採用 symfony 提供的載入預設資料功能
      ./symfony propel-13-load-data frontend /usr/local/www/flavor/data/fixtures/sfGuardProfile.data
      
    3. 不過目前 symfony 的 sfPropel13Plugin 所提供的功能似乎沒有很健全,所以會發生失敗,可以手動建立資料取代:
      psql=> insert into sf_guard_career (name) values ('engineer');
      psql=> insert into sf_guard_career_i18n (career_id, culture, name_l10n) values (1, 'en', 'Engineer');
      
  8. 利用 app.yml 提供支援 sfGuardUserProfile 的介面設定
    all:
      sf_guard_plugin:
        profile_class:      sfGuardUserProfile
        profile_field_name: user_id
    
  9. 存取 sfGuardUserProfile 中的物件函式的方式:
    $this->getUser()->getGuardUser()->getProfile()->getFirstName()
    
    // or via the proxy method
    $this->getUser()->getProfile()->getFirstName()
    

制式化樣版

  1. 在需要支援 sfGuardAuth 的 application 下建立 sfGuardAuth/templates 目錄,以自訂化檔案
    1. 預設支援的樣版檔案:
      1. signinSuccess.php
      2. secureSuccess.php
    2. 範例:
      % mkdir [project name]/apps/[application name]/modules/sfGuardAuth/templates/
      % cd [project name]/apps/[application name]/modules/sfGuardAuth/templates/
      % echo "hellp this is signinSuccess.php template" > signinSuccess.php
      

擴充 sfGuardPlugin 支援的功能

  1. 在 application 的目錄下增加 sfGuardAuth/actions 目錄
  2. 檔案為: actions.class.php
  3. 範例內容:
    <?php
    
    require_once(sfConfig::get('sf_plugins_dir').'/sfGuardPlugin/modules/sfGuardAuth/lib/BasesfGuardAuthActions.class.php');
    
    class sfGuardAuthActions extends BasesfGuardAuthActions
    {
      public function executeHello()
      {
        return $this->renderText('This is a new sfGuardAuth action.');
      }
    }
    
    ?>
    
  4. 增加對應的 routing 設定,提供新的功能支援
    1. 檔案: [projace name]/apps/[frontend application]/config/routing.yml
    2. 這些設定同樣也要加在 default 之前,不然會被 default 攔截走內容:
      sf_guard_hello:
        url:   /hello
        param: { module: sfGuardAuth, action: hello }
      

… reply

簡易的 YAML 檔案讀取方式

5 months, 4 weeks ago in by MoyaTseng
其實 YAML 的檔案設計性質與 XML 非常接近,幾乎所有 XML 做得到的,採用 YAML 也都可以做到。但是 YAML 又具有比 XML 還要適合人類的閱讀習慣,以及執行速度快、傳輸的時候的資料量也比較小等優點。

就算有這些的優點存在,但是 YAML 能不能成為 XML 之後另外一個資料交換格式?那就很難說了。畢竟 XML 也是經過十餘年的掙扎才活下來的,要能夠取代他,談何容易?只不過目前 Symfony 這個 PHP framework 已經確立了要採用 YAML 作為設定的標準格式了,所以相較之下,如果是採用 Symfony 開發專案的人,學會 YAML 已經成為標準必備的基礎知識。

既然 Symfony 把 YAML 當成他的標準設定格式,所以她也必然會提供一些 YAML 相關的函示。

所以,在 Symfony 當中要讀取 YAML 的檔案,非常簡單:

$test = sfYaml::load('sample.yaml');
print_r($test);

這個範例,就已經把 sample.yaml 當中的設定檔,以 PHP array 的方式載入,之後要如何運用這些設定的資料就很方便了。

詳細的 YAML 資料,可以參考 YAML Ain't Markup Language External link mark

… reply

利用 SimpleXML 產生 XML 格式的輸出內容

6 months, 1 week ago in by MoyaTseng
上次介紹如何用 PHP 的 SimpleXML 讀取一個既有的 XML 檔案,並且將這個內容轉成 array。這一次來介紹怎樣利用 SimpleXML 來建立一個全新的 XML 檔案。

簡易產出 XML 文檔的程式撰寫說明

函示使用說明

  1. 建立一個基礎的 XML 文檔
    $body = "<?xml version='1.0' standalone='yes'?>
    <files>
    </files>";
    $sxe = new SimpleXMLElement($body);
    
  2. 增加屬性
    $sxe->addAttribute(type, configuration);
    
  3. 增加子節點
    $movie = $sxe->addChild(node);
    
  4. 增加子節點的物件
    $movie->addChild(key, value);
    
  5. 輸出既有的 XML 內容
    echo $sxe->asXML();
    

簡單的範例程式

<?php

 $sxe = new SimpleXMLElement("<?xml version='1.0' standalone='yes'?>
<files>
</files>");
 $sxe->addAttribute('type', 'documentary');

 $movie = $sxe->addChild('file');
 $movie->addChild('snapshot', 'file-1.jpg');
 $movie->addChild('movie', 'file-1.wmv');

 $movie = $sxe->addChild('file');
 $movie->addChild('snapshot', 'file-2.jpg');
 $movie->addChild('movie', 'file-2.wmv');

 echo $sxe->asXML();

?>

程式執行結果

<?xml version="1.0" standalone="yes"?>
<files type="documentary">
  <file>
    <snapshot>file-1.jpg</snapshot>
    <movie>file-1.wmv</movie>
  </file>
  <file>
    <snapshot>file-2.jpg</snapshot>
    <movie>file-2.wmv</movie>
  </file>
</files>

… reply

訪客統計: 149202 人次



請按此訂閱每日人間菩提。靜思晨語 External link mark
本站所有言論均不代表慈濟基金會 External link mark


我為你祝福
我也要許願

r1 - 21 Mar 2008 - 15:29:51 - MoyaTseng
Copyright © 1999-2008 by the contributing authors. All material on this collaboration platform is the property of the contributing authors. Ideas, requests, problems regarding Moya's Blog? Send feedback.