2010年7月10日 星期六

XML符號對應

有一些字元,如"<"和"&"在XML資料裡嚴格來說是不合法的。
其他像">"則是合法的,但習慣上最好將這些字元置換成XML的實體對應。
以下列示出XML裡事先定義好的實體對應:

原先字元     實體對映          
<                   &lt;           
>                   &gt;
&                  &amp;
'                    &apos;
"                   &quot;

PHP跨資料庫應用淺談

寫一下目前查資料之後的結果
當然實際的驗證及比較要先等一段時間後,有空再去把這些都學完

目前較常拿來做比較的跨資料庫抽象層應用大致上有MDB2、ADOdb、PDO三種

MDB2的優點在於pear的套件取得上較為容易,開發較不會有客戶端缺少開發環境的問題
當然套件的相依性會是比較麻煩的議題
資料庫處理速度不錯,算是各方面都有中上表現的選擇
詳情可以看MDB2筆記

ADOdb以微軟的ADO為基底所製作,很多習慣使用ASP的使用者會比較喜歡ADOdb
它有蠻多強大的功能,卻也因為過於龐大讓資料庫處理速度慢的缺點浮現
官方網站有提供Lite版本,大小大約是原本的1/6
不過因為缺少許多強大的ADOdb功能,如果原先有使用那些功能的話還要改變程式的寫法
官方網站:http://adodb.sourceforge.net/
熱心人士翻譯的手冊:http://www.php5.idv.tw/documents/ADODB/

PDO是PHP5以後新增加的功能,也會是以後PHP6預設的資料庫處理方式
資料庫處理的速度會是目前PHP選擇中最快的
因為PHP5.3後物件導向方面的變化不小,學習及使用上要更加注意

2010年7月8日 星期四

MDB2使用筆記(2)

上篇介紹了如何建立資料庫的連線
接著來說說MDB2的query部分,總共有query()和exec()兩種
成功會回傳結果,失敗則都會回 傳MDB2_Error訊息
差別在於query()是執行sql指令並取得值
exec()則是單純的執行指令,適用於 INSERT、UPDATE或DELETE

query()範例:
// Proceed with a query
$res =  $mdb2->query('SELECT * FROM clients');

// Always check that result is not an error
if (PEAR::isError($res)) {
    die($res->getMessage());
}

exec() 範例:
$sql  = "INSERT INTO clients (name, address) VALUES ($name, $address)";

$affected = $mdb2->exec($sql);

// Always check that result is not an error
if (PEAR::isError($affected)) {
    die($affected->getMessage());
}

另 外在查詢時一樣可以設定查詢的範圍及起點
$sql = "SELECT * FROM clients";
$mdb2->setLimit(20, 10);                 //回傳20筆資料,從第10筆資料後開始算起
$affected =& $mdb2->exec($sql);

$sql = "DELETE FROM clients";
if ($mdb2->supports('limit_queries') === 'emulated') {
    echo 'offset will likely be ignored'
}
// only delete 10 rows
$mdb2->setLimit(10);
$affected =& $mdb2->exec($sql);

查詢時可以使用quote()提高資料存取的安全性, 例如:
$query = 'INSERT INTO sometable (textfield1, boolfield2, datefield3) VALUES ('
    .$mdb2->quote($val1, "text", true).', '
    .$mdb2->quote($val2, "boolean", false).', '
    .$mdb2->quote($val3, "date", true).')';

quote() 函式只有第一個參數-值是需要的,後面的三個參數則是視需求使用
第二個參數是值的類別,可以排除設定類別外的值
允許使用的有text, boolean, integer, decimal, float, time stamp, date, time, clob, blob
第三個參數是是否使用quote(),即用引號包住值,false的話則只是單純的將值輸出
第四個參數則是使否要脫離萬用字元
善用quote()可以增加安全性

針對query出來的結果也可以調整表現的方式,例如:
$mdb2->setFetchMode(MDB2_FETCHMODE_ASSOC);
setFetchMode() 有三種屬性
MDB2_FETCHMODE_ORDERED(例:$result[0])
MDB2_FETCHMODE_ASSOC(例:$result['name'])
MDB2_FETCHMODE_OBJECT(例:$result->name)

取得結果之後,接著就是要用函式來取出值
fetchOne(), fetchRow(), fetchCol() and fetchAll()這四個函式看起來就很容易懂
分別是取一個,取一行,取一列,取所有
此外 numRows(), numCols(), rowCount()等函式也可以獲取結果的其他資訊

除了以上處理過程外,也有函式可以幫助簡化撰寫,直接取得結果
就是queryOne(), queryRow(), queryCol() and queryAll()這四個對應的函式

以範例作比較,使用query():
$res = $mdb2->query("select ID,name,birthday from member");
while ($data = $res->fetchRow()) {
  echo $data['ID'].','.$data['name'].','.$data['birthday'];
}

queryOne():
$res = $mdb2->queryOne("select count(*) from member");
if (!is_null($res)) echo $res;

queryRow():
$res = $mdb2->queryRow("select name,birthday from member where ID = 1");
if (!is_null($res)) echo $res['name'].','.$dbquery['birthday'];

依此類推,依需求選擇使用的函式

MDB2尚有預編譯及批量處理Prepare & Execute、moudle等好用功能沒提到
等之後有用到再去查技術手冊了

MDB2使用筆記(1)

來自官方的說明:

PEAR MDB2 is a merge of the PEAR DB and Metabase php database abstraction layers.

It provides a common API for all supported RDBMS. The main difference to most  other DB abstraction packages is that MDB2 goes much further to ensure  portability.


MDB2整合了過去的 PEAR:db函式的新類別庫,為目前PEAR官方所支持
其有許多選擇性的功能,可以增加對各種資料庫系統間資料的可攜性
很適合作為跨資料庫的選擇

MDB2的安裝可以使用套件管理員來進行,詳情可以參考PEAR安裝教學那篇
或者是到PEAR套件官網下載,下載時要連同所連結的資料庫的驅動一起下載
以下簡介使用方式,詳細解說可以到官方說明手冊看

首先來個修改自官網的範例:
 <?php
require_once 'MDB2.php';

$dsn = array(
    'phptype'  => 'mysqli',             //輸入所要連結的資料庫類別
    'username' => 'user',
    'password' => 'pw',
    'hostspec' => 'localhost',
    'database' => 'DBname',
    'charset' => 'utf8',
);

$options = array(
    'debug'       => 2,                                                  //numeric debug level
    'portability' => MDB2_PORTABILITY_ALL,
);

$mdb2 =& MDB2::connect($dsn, $options);
if (PEAR::isError($mdb2)) {
    die($mdb2->getMessage(). ', ' . $mdb2->getDebugInfo() );
}

$mdb2->disconnect();
?>

首先要使用PEAR的套件都必須先將使用的檔案include
dsn是Data Source Name,用來記錄資料庫資訊
另外,也可以寫成  $dsn = 'mysqli://user:pw@localhost/DBname';
options當然就是額外的附屬要求
需要一提的是portability選項
除非設置成了MDB2_PORTABILITY_NONE,否則query出來的結果都是小寫
例如結果不可能會有  echo $array['A'];
官方的預設是小寫,目的是要達到各種資料庫的相容性,當然這也是MDB2的原則

資料庫的連結方式有三種
&MDB2::connect 建立MDB2物件並連線資料庫
&MDB2::factory 建立MDB2物件,但等到要進行資料庫操作時才連線
&MDB2::singleton 同factory,但它保證只有一個MDB2物件連線到資料庫
想用哪個就用哪個,一般使用下應是factory效率較高
最後用disconnect()來結束連線

連線與結束連線可以以global variable的方式寫成function來增加使用的方便性
可以參考這篇文章

官網那邊尚有使用SSL來建立連線的範例,如下:
<?php
require_once 'MDB2.php';

$dsn = array(
    'phptype'  => 'mysqli',
    'username' => 'someuser',
    'password' => 'apasswd',
    'hostspec' => 'localhost',
    'database' => 'thedb',
    'key'      => 'client-key.pem',
    'cert'     => 'client-cert.pem',
    'ca'       => 'cacert.pem',
    'capath'   => '/path/to/ca/dir',
    'cipher'   => 'AES',
);

$options = array(
    'ssl' => true,
);

// gets an existing instance with the same DSN
// otherwise create a new instance using MDB2::factory()
$mdb2 =& MDB2::singleton($dsn, $options);
if (PEAR::isError($mdb2)) {
    die($mdb2->getMessage());
}
?>

PHP特殊符號

PHP除了一般運算時常見的符號以外,另外還有些符號較特殊

$         變數宣告符號
&        變數指標(加在變數前)
@      不顯示錯誤訊息(加在函數前)
->       物件的方法或者屬性
=>      陣列的元素值
? :      三元運算子

2010年7月5日 星期一

Flex調整物件重疊順序

Flex中的元件重疊問題很少被提到
因為Flex的運作方式是後來增加的物件會被排列在已有物件的上層
所以要調整物件重疊的先後順序就必須調整物件的加入順序
範例:
private function mouseOverHandler(event:MouseEvent):void{
  this.setChildIndex(event.currentTarget as UIComponent,this.numChildren-1);
}

這個function對讓所點擊的物件的加入順序做改變

Flex使用addChild加入flash.display類別元件

在Flex中使用addChild來加入Sprite、MovieClip等flash.display類別物件須經過處理
直接使用時會回傳強制轉換型別失敗
這是因為Application的 addChild() 並非完全繼承自DisplayObjectContainer

Application→LayoutContainer→Container→UIComponent→FlexSprite→Sprite
 →DisplayObjectContainer

而 addChild() 在Container那裡被覆寫了︰
public override function addChild(child:DisplayObject):DisplayObject

雖然參數child的類型是DisplayObject
但它必須實作IUIComponent介面後才能加入,就如同其他所有Flex元件都必須實作這個介面
如果要在Application裡添加Sprite,可以先把它裝進UIComponent裡
或者用UIMOVIECLIP,然後再添加這個UIComponent︰

import mx.core.UIComponent;

private function init():void {   
  var sp:Sprite = new Sprite();
  var uc:UIComponent = new UIComponent();   
  uc.addChild(sp);   
  addChild(uc);
}