PHP
PHP Programming PHP 程式設計相關文獻整理
|
|
|
5 months, 1 week ago in PHP by MoyaTseng
Symfony 支援了數種常見的 Session 控制機制,包括
- sfSessionStorage
- sfMySQLSessionStorage
- sfPostgreSQLSessionStorage
- sfMemcacheSessionStorage
個人不覺得用 database 當 session 的 backend storage 會是個好主意,很容易會卡在 database 的 performance 上。當然使用 PHP 內建的單機版本的也沒有什麼擴充性可言,所以也不考慮。
個人比較推薦採用外掛 Plugin 所支援 memcached 或是 memcachedb 的機制,會比內建的三種機制都來得適當一些。在 Performance 上會有很大的改進,而且,擴充性也會比較好。
參考文件
與 Session 相關的設定
Session 儲存體的機制設定
- 檔案:apps/[app-name]/config/factories.yml
- 內容:
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]
- 可以用的 storage class 包括
- sfSessionStorage
- sfMySQLSessionStorage
- sfPostgreSQLSessionStorage
- sfMemcacheSessionStorage (非 symfony 內建提供機制,需要加裝 sfAdvMemcachedCache 套件)
用途:設定 timeout 的時間
- 檔案:apps/[app-name]/config/settings.yml
- 內容:
default:
.settings:
timeout: 1800 # Session lifetime in seconds
支援的 Session 儲存體
- sfSessionStorage
- 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. |
- sfPDOSessionStorage
- 採用 PDO Database 的 Session Storage
- 參數設定與 sfMySQLSessionStorage 相同
- sfPostgreSQLSessionStorage
- 採用 PostgreSQL Database 的 Session Storage
- 參數設定與 sfMySQLSessionStorage 相同
- sfMemcacheSessionStorage
存取控制
存取設定
- 檔案:apps/[app-name]/modules/[module-name]/config/security.yml
- 內容:
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
預設行為定義
- 檔案:apps/[app-name]/config/settings.yml
- 內容:
all:
.actions:
login_module: default
login_action: login
secure_module: default
secure_action: secure
5 months, 1 week ago in PHP 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
- The sfPropel13 Plugin
Install sfPropel13Plugin
- cd /usr/local/share/pear/symfony/plugins
- svn co http://svn.symfony-project.com/plugins/sfPropel13Plugin/ sfPropel13Plugin
目的
- 採用 sfPropel13Plugin 為基礎架構
- Propel-1.3 採用的是 PHP 內建的 PDO,比 symfony 1.0 目前所用的 Creole 有更好的效能,而 PDO 要到 symfony 1.1 才會支援的。
參考文件
- Upgrading to Propel 1.3
- using propel 1.3
- sfPropel13Plugin - The power of Propel 1.3
- The sfPropel13 Plugin
初始化專案
- cd /usr/local/www/[project name]
- symfony init-project
- symfony init-app frontend
安裝需要的套件
- sfPropel13Plguin
cd ~[project name home path]/plugins
mkdir sfPropel13Plugin
svn co http://svn.symfony-project.com/plugins/sfPropel13Plugin/ sfPropel13Plugin
資料庫的相關設定
- 以 sfPropel13Plugin 作為 database 的 backend
propel.ini 設定
- 檔案: [project name]/config/propel.ini
- 相關的內容設定:
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 設定
- 檔案: [project name]/config/databases.yml
- 相關的內容設定:
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
重建專案
- 清除既有的專案 cache
symfony cc
- 依據 sfPropel13Plguin 建立 database backend 相關 model
symfony propel-13-build-all
sfPropel13Plugin 所支援的 model functions
5 months, 1 week ago in PHP by MoyaTseng
網路上的文件的說明都不是很完整,所以花了滿多的時間才搞定基本的功能瞭解,事實上還不是真的非常清楚整個架構,或許未來有機會進行進一步的深入瞭解,到時候可以再提供更深入的使用說明。
其實至少還要支援 sfCaptchaPlugin 的支援才是真的完成了符合現今流行的會員網站的最基本架構。那個部分等我把 sfGuardPlugin 瞭解得更透徹之後再提供如何加上那個功能的說明吧。
目的
- 採用 sfPropel13Plugin 為基礎架構
- 支援 sfGuardPlugin 為登入與認證管控機制
參考文件
- Howto do a Captcha in Symfony - with Plugins
- sfGuard plugin - extra documentation
- sfGuardPluginPlus
- How To Extend Propel Plugin Model
- How to override sfGuardUser
初始化專案
- cd /usr/local/www/[project name]
- symfony init-project
- symfony init-app frontend
- symfony init-app backend
安裝需要的套件
- sfGuardPlugin
symfony plugin-install http://plugins.symfony-project.com/sfGuardPlugin
- sfPropel13Plguin
cd ~[project name home path]/plugins
mkdir sfPropel13Plugin
svn co http://svn.symfony-project.com/plugins/sfPropel13Plugin/ sfPropel13Plugin
為支援 sfProepl13Plugin 進行 sfGuardPlugin patch
- 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
- 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
- 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
- ./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
- 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 設定
- 檔案: [project name]/config/propel.ini
- 相關的內容設定:
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 設定
- 檔案: [project name]/config/databases.yml
- 相關的內容設定:
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 介面功能
安裝的套件
- for the frontend-application
- sfGuardAuth
- for the backend-application
- sfGuardGroup
- sfGuardPermission
- sfGuardUser
新增的 Schema
- 檔名: [project name]/plugins/sfGuardPlugin/config/schema.yml
- 檔案內容:
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
- 先完成要啟用 sfGuardPlugin 相關 application 設定的更改
- 清除既有的 cache 檔案
symfony cc
- 構建支援 sfGuardPlugin 的系統
symfony propel-13-build-all
Module 啟用相關設定
- 啟用 Module
- 檔案: [project name]/apps/[frontend application]/config/settings.yml
- 內容:
all:
.settings:
enabled_modules: [default, sfGuardAuth]
- 檔案: [project name]/apps/[backend application]/config/settings.yml
all:
.settings:
enabled_modules: [default, sfGuardGroup, sfGuardUser, sfGuardPermission]
- 設定 Login 和 Secure 的 default action module
- 檔案: [project name]/apps/[frontend application]/config/settings.yml
- 內容:
all:
.actions:
login_module: sfGuardAuth
login_action: login
secure_module: sfGuardAuth
secure_action: secure
- 關閉 sfGuardAuth 的預設 routing 設定,取消預設的控制行為
- 檔案: [projace name]/apps/[frontend application]/config/app.yml
- 內容:
# default values
all:
sf_guard_plugin:
routes_register: false
- 設定 signin, signout, request_password 的相關 action module 及 url
- 檔案: [projace name]/apps/[frontend application]/config/routing.yml
- 這些設定要加在 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 }
- apps/frontend/config/security.yml
default:
is_secure: on
程式調整,支援 sfGuardPlugin
- sfGuardPlugin 提供了一個 sfGuardSecurityUser,而 sfGuardSecurityUser 繼承自原來的 sfBasicSecurityUser,所以不會遺失任何 sfBasicSecurityUser 的功能。
- 修改 [project name]/apps/frontend/lib/myUser.class.php 把繼承來源的 class 調整為來自於 sfGuardPlugin 的版本
class myUser extends sfGuardSecurityUser
{
}
管理介面
- URL: http://[hostname]/backend.php/sfGuardUser
- 依據提供的預設介面即可新增、刪除、查詢既有的使用者帳號
依據 sfGuardPlugin 擴充會員系統功能
增加自訂的 database schema
- 在 sfGuardPlugin 當中所支援的 database schema 相當有限,只包括了:
- username
- algorithm
- salt
- password
- created_at
- last_login
- is_active
- is_super_admin
- 預設 sfGuardUser 會參考 sfGuardUserProfile 來提供額外的 database schema 支援
- 要增加額外的 database schema,不需要修改 plugin 的 schema.yml 只要在自己專案的 schema.yml 增加相關的 datbase schema 即可
- 檔案: [project name]/config/schema.yml
- 內容:
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 }
- 建立相關的資料庫與功能模組
symfony cc
symfony proepl-13-build-all
- 執行完以上的程序之後,資料庫中會建立 sf_guard_user_profile 這個資料庫
- 也會同時建立一下的 modules libraries
- [project name]/lib/model/sfGuardUserProfilePeer.php
- [project name]/lib/model/sfGuardUserProfile.php
- [project name]/lib/model/map/sfGuardUserProfileMapBuilder.php
- [project name]/lib/model/om/BasesfGuardUserProfile.php
- [project name]/lib/model/om/BasesfGuardUserProfilePeer.php
- 預設的資料
- 預設的資料內容, 檔案: [my project]/data/fixtures/sfGuardProfile.data
sfGuardCareer:
sfGuardCareer_1:
name: engineer
sfGuardCareerI18n:
sfGuardCareerI18n_1_1_en:
name_l10n: Engineer
- 採用 symfony 提供的載入預設資料功能
./symfony propel-13-load-data frontend /usr/local/www/flavor/data/fixtures/sfGuardProfile.data
- 不過目前 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');
- 利用 app.yml 提供支援 sfGuardUserProfile 的介面設定
all:
sf_guard_plugin:
profile_class: sfGuardUserProfile
profile_field_name: user_id
- 存取 sfGuardUserProfile 中的物件函式的方式:
$this->getUser()->getGuardUser()->getProfile()->getFirstName()
// or via the proxy method
$this->getUser()->getProfile()->getFirstName()
制式化樣版
- 在需要支援 sfGuardAuth 的 application 下建立 sfGuardAuth/templates 目錄,以自訂化檔案
- 預設支援的樣版檔案:
- signinSuccess.php
- secureSuccess.php
- 範例:
% 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 支援的功能
- 在 application 的目錄下增加 sfGuardAuth/actions 目錄
- 檔案為: actions.class.php
- 範例內容:
<?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.');
}
}
?>
- 增加對應的 routing 設定,提供新的功能支援
- 檔案: [projace name]/apps/[frontend application]/config/routing.yml
- 這些設定同樣也要加在 default 之前,不然會被 default 攔截走內容:
sf_guard_hello:
url: /hello
param: { module: sfGuardAuth, action: hello }
5 months, 4 weeks ago in PHP 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
6 months, 1 week ago in PHP by MoyaTseng
上次介紹如何用 PHP 的 SimpleXML 讀取一個既有的 XML 檔案,並且將這個內容轉成 array。這一次來介紹怎樣利用 SimpleXML 來建立一個全新的 XML 檔案。
簡易產出 XML 文檔的程式撰寫說明
函示使用說明
- 建立一個基礎的 XML 文檔
$body = "<?xml version='1.0' standalone='yes'?>
<files>
</files>";
$sxe = new SimpleXMLElement($body);
- 增加屬性
$sxe->addAttribute(type, configuration);
- 增加子節點
$movie = $sxe->addChild(node);
- 增加子節點的物件
$movie->addChild(key, value);
- 輸出既有的 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>
|
|
|
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.
|
|