2007年12月27日 星期四

如果自己現在開發的程式希望相容於 PHP6

如果自己現在開發的程式希望相容於 PHP6 , 應該怎麼修正 ..

以下紅色文字表示較有可能影響一般 programmer 的項目 .
  藍色文字表示較有可能影響 OO programmer 的項目 .

.Unicode 的支援 -
    讓多數的 functions 支援處理 unicode

.register globals 將被移除 -
    這早就該做了啊 XDDD
    趕快改掉不良的習慣吧 !!

.magic quotes 將被移除 -

2007年12月24日 星期一

jQuery Resource

http://visualjquery.com/1.1.2.html

2007年10月9日 星期二

視窗間 傳值

http://swf.com.tw/?p=50
http://news.hping.org/comp.lang.javascript.archive/0935.html

2007年9月27日 星期四

id屬性用於IE瀏覽器,
name屬性則用於Netscape和FireFox瀏覽器。

轉載自網路


目前的 Ajax Library 大概都包含四個部分:JS&Dom Improvement、Ajax Connection Management、Visual Effect 與 UI Widget。

Ajax Libary 比較:

Package NameJS Core & DOM ImprovementAjax Connection ManagementVisual EffectUI Widget
Prototype:這是最有名的 Ajax Library,除了對 Javascript 的 Object 與 DOM 有很豐富的擴充功能外,還有完整的 Ajax 連線管理。唯一可惜的是沒有任何 Visual Effect 與 UI Widget。目前 LifeType 1.1 的 Ajax 就是用 Prototype 來作的。OO  
Script.aculo.us:基於 Prototype 所發展的 Visual Effect Library。 RoR 就是用他來作為 UI 發展的基礎。  O 
Rico:跟 Script.aculo.us 一樣是基於 Prototype 所發展的 Visual Effect。LifeType 目前使用他 Resize 的功能。 OO 
moo.fx:同 Script.aculo.us 與 Rico,但是他是基於 Prototype Lite 為基礎來發展,所以程式很小。 OO 
SACK:WordPress 所使用的 Ajax Library。很單純的只負責 Ajax 的連線管理。 O  
Dojo Toolkit:我用過最肥的 Ajax Library,實在是很耗空間與時間。雖然他有很豐富的 UI Widget。但是,實在是不建議啊!不過很多人覺得很好用就是了。OOOO
Yahoo UI Library:今天才看到的,試了一下,只有一句話:『驚人的 Yahoo ...』OOOO

 

2007年9月19日 星期三

CSS include

@import url(default/dialogs.css);
@import url(default/layout.css);
@import url(default/display.css);

鎖右鍵配套

Onbody
onDragStart="return false"
onContextmenu="return false"
onSelectStart="return false"


取消浮現 IE Tool Bar
meta http-equiv="imagetoolbar" content="no"

2007年8月29日 星期三

GraPHPite

SourceForge.net GraPHPite aka Image_Graph

GraPHPite

SourceForge.net GraPHPite aka Image_Graph

2007年8月11日 星期六

2007年8月10日 星期五

Yahoo拍賣搬到露天拍賣

http://blog.xuite.net/supertwobow/blog/7546907

2007年8月6日 星期一

note

1.group_content combine content_destination,
if publish user_content_hash,group_content_hash to destination or not.
2.take off friend cache for testing and develop

2007年8月4日 星期六

圖片 壓縮樣式

http://tools.dynamicdrive.com/imageoptimizer/index.php

2007年8月2日 星期四

[smarty] Warning: Cannot modify header information - headers already sent

可能有兩種情況:
1.你的plugin在 <?php?>前後有多餘的空白,這是國外網站看到的.
2.有別的plugin衝到,可試試把其他的plugin deactivate 看看.

linux command

wget http://127.0.0.1/fixtools/buildDir.php -O /dev/null

command open web page~~ then avoid directory owner setting...bala bala

2007年7月28日 星期六

HessianPHP,PHPolait

HessianPHP:
include_once '/HessianPHP/dist/HessianClient.php';
$url = 'http://192.168.1.196:8080/relation/relation.service';
$service = new HessianClient($url);
$service->requestRelation(8,9,"救命啊");
$result = $service->getPendingRequestBy(9,0,1) ;

phpolait:
require_once("/phpolait/phpolait.php");
$service = new JSONRpcProxy("http://192.168.1.196:8080/relation/jsonrpc");
$result = $service->__call("relation.getDirectRelations", array($from_id,0,1));

2007年7月25日 星期三

Turnning

Message Box :
limit >50 , then drop
memcached user.inbox_num

2007年7月15日 星期日

電子地圖

http://www.map.com.tw/
example: http://cathaybk.map.com.tw/

電子地圖

http://www.map.com.tw/
example: http://cathaybk.map.com.tw/

2007年7月3日 星期二

待做待討論

Rss : efun rss url => feedburner

2007年6月29日 星期五

Url link, Tmp DB for Memcached, Blog, Index Blog

Url link rule => Web Function Map and Naming
Tmp DB => Memcached
Blog Function
Index => New Albums, New Blogs

2007-06-29

2007年6月27日 星期三

PHP5 XML sample

/************************************************
** use XML in PHP5
** reference site:
** http://cn.php.net/manual/zh/ref.dom.php
** the follow codes need PHP5 support
** www.knowsky.com
*************************************************/


//首先要创建一个DOMDocument对象
$dom = new DomDocument();
//然后载入XML文件
$dom -> load("test.xml");

//输出XML文件
//header("Content-type: text/xml;charset=gb2312");
//echo $dom -> saveXML();

//保存XML文件,返回值为int(文件大小,以字节为单位)
//$dom -> save("newfile.xml");

echo "
取得所有的title元素:
";
$titles = $dom -> getElementsByTagName("title");
foreach ($titles as $node)
{
echo $node -> textContent . "
";
//这样也可以
//echo $node->firstChild->data . "
";
}

/*
echo "
从根结点遍历所有结点:
";
foreach ($dom->documentElement->childNodes as $items) {
//如果节点是一个元素(nodeType == 1)并且名字是item就继续循环
if ($items->nodeType == 1 && $items->nodeName == "item") {
foreach ($items->childNodes as $titles) {
//如果节点是一个元素,并且名字是title就打印它.
if ($titles->nodeType == 1 && $titles->nodeName == "title") {
print $titles->textContent . "\n";
}
}
}
}
*/

//使用XPath查询数据
echo "
使用XPath查询的title节点结果:
";
$xpath = new domxpath($dom);
$titles = $xpath->query("/rss/channel/item/title");
foreach ($titles as $node)
{
echo $node->textContent."
";
}
/*
这样和使用getElementsByTagName()方法差不多,但是Xpath要强大的多
深入一点可能是这样:
/rss/channel/item[position() = 1]/title 返回第一个item元素的所有
/rss/channel/item/title[@id = '23'] 返回所有含有id属性并且值为23的title
/rss/channel/&folder&/title 返回所有articles元素下面的title(译者注:&folder&代表目录深度)
*/


//向DOM中写入新数据
$item = $dom->createElement("item");
$title = $dom->createElement("title");
$titleText = $dom->createTextNode("title text");
$title->appendChild($titleText);
$item->appendChild($title);
$dom->documentElement->getElementsByTagName('channel')->item(0)->appendChild($item);

//从DOM中删除节点
//$dom->documentElement->RemoveChild($dom->documentElement->getElementsByTagName("channel")->item(0));
//或者使用xpath查询出节点再删除
//$dom->documentElement->RemoveChild($xpath->query("/rss/channel")->item(0));
//$dom->save("newfile.xml");

//从DOM中修改节点数据
//修改第一个title的文件
//这个地方比较笨,新创建一个节点,然后替换旧的节点。如果哪位朋友有其他好的方法请一定要告诉我
$firstTitle = $xpath->query("/rss/channel/item/title")->item(0);
$newTitle = $dom->createElement("title");
$newTitle->appendChild(new DOMText("This's the new title text!!!"));
$firstTitle->parentNode->replaceChild($newTitle, $firstTitle);
//修改属性
//$firstTitle = $xpath->query("/rss/channel/item/title")->item(0);
//$firstTitle->setAttribute("orderby", "4");
$dom->save("newfile.xml");

echo "
查看newfile.xml";

//下面的代码获得并解析php.net的首页,将返第一个title元素的内容。
/*
$dom->loadHTMLFile("http://www.php.net/");
$title = $dom->getElementsByTagName("title");
print $title->item(0)->textContent;
*/
?>

下面是test.xml文件代码:




javascript
http://blog.csdn.net/zhongmao/category/29515.aspx
javascript
zh-chs
.text version 0.958.2004.2001

zhongmao
out put excel used javascript
http://blog.csdn.net/zhongmao/archive/2004/09/15/105385.aspx
wed, 15 sep 2004 13:32:00 gmt
http://blog.csdn.net/zhongmao/archive/2004/09/15/105385.aspx
http://blog.csdn.net/zhongmao/comments/105385.aspx
http://blog.csdn.net/zhongmao/archive/2004/09/15/105385.aspx#feedback
2
http://blog.csdn.net/zhongmao/comments/commentrss/105385.aspx
http://blog.csdn.net/zhongmao/services/trackbacks/105385.aspx
test description


zhongmao
out put word used javascript
http://blog.csdn.net/zhongmao/archive/2004/08/06/67161.aspx
fri, 06 aug 2004 16:33:00 gmt
http://blog.csdn.net/zhongmao/archive/2004/08/06/67161.aspx
http://blog.csdn.net/zhongmao/comments/67161.aspx
http://blog.csdn.net/zhongmao/archive/2004/08/06/67161.aspx#feedback
0
http://blog.csdn.net/zhongmao/comments/commentrss/67161.aspx
http://blog.csdn.net/zhongmao/services/trackbacks/67161.aspx
test word description


zhongmao
xmlhttp
http://blog.csdn.net/zhongmao/archive/2004/08/02/58417.aspx
mon, 02 aug 2004 10:11:00 gmt
http://blog.csdn.net/zhongmao/archive/2004/08/02/58417.aspx
http://blog.csdn.net/zhongmao/comments/58417.aspx
http://blog.csdn.net/zhongmao/archive/2004/08/02/58417.aspx#feedback
0
http://blog.csdn.net/zhongmao/comments/commentrss/58417.aspx
http://blog.csdn.net/zhongmao/services/trackbacks/58417.aspx
xmlhttpaaa asd bb cc dd


2007年6月7日 星期四

javascript collect

http://javascript.internet.com/
http://irw.ncit.edu.tw/peterju/jscript.html

2007年6月6日 星期三

b2evolution 0.9.0.11

http://b2evolution.net/

ref:
http://www.j2.idv.tw/jimmy/b2.php?cat=41

b2evolution 0.9.0.11 -- SQL injection security issue

if( !empty( $title ) )
{
$where .= " AND post_urltitle = '$title'";//$DB->quote($title) avoid sql injection
}


function quote($str)
{
if( $str === NULL )
return 'NULL';
else
return "'".mysql_real_escape_string($str)."'";
}

unknow tag?

http://textbook.textpattern.net/wiki/index.php?title=Zh-tw/txp:thumbnail_/

2007年6月5日 星期二

Website Thumbnail

copied from
http://liguangming.com/archives/2007/02/1171940758.html

现在许多站长正在寻找为网站创建快照(缩微图)的工具,以便显示网站更多的数据,从而吸引更多的访问者。在搜索结果网页使用缩略图,对产品细节页手工制作网页缩略图等,是常用的程序,需要大量时间,而对于大站则需要专门的来处理.下面我们将通过这一过程自动化,提供一些建议.
1:从其他网站抓取缩微图
一些搜索引擎,象http://www.alexa.com , http://www.exalead.com等网站,提供了快照. 可写脚本语言(如PHP的,Perl的,等等)从他们攫取搜索网站形象的效果.
好处:
廉价
小型服务器负载既然你不需要你创造缩微图服务器。
弊端:
依赖第三方服务器。
结果有限。
速度慢,受第三方服务器速度影响。
不稳定,他们随时有可能禁止这一服务。虽然你可以用匿名投票工具,但它会减慢负荷页。
你将无法获得网站缩略图,如果缩略图未产生但提供商的网站.这意味着你会经常收到"没有缩略图"形象.
通常预先大小不一定是你需要的
2:使用现有的网站缩微图服务或工具。
有些网站缩略图/快照可供自由创作工具.你希望把你的HTML提供的一砖一页它将显示缩略图,PHP的一个例子可以从artviper工具(http://www.artviper.com/tools.php).据说,它是利用PHP的脚本的C++DLL的编码生成网站缩略图.
另一个例子是免费服务网站缩略图服务http://www.websitethumbnails.net
使用教程:http://www.web-development-blog.com/archives/dynamic-thumbnails-from-websites/
好处:
廉价
小型服务器负载既然你不需要你创造缩微图服务器。
弊端:
你依赖第三方服务器(有时甚至可以向下)
你最可能只能得到的最高缩略图只有一页.这些都不是主要的。要获取全部缩微图,需要付出额外的费用
如果第三方速度慢,你的网页速度也会随之变慢.
你将无法获得网站缩略图,如果缩略图未产生但提供商的网站.这意味着你会经常收到"没有缩略图"形象.
通常预先大小不一定是你需要的。
需要支付额外费用才能获取自定义功能。
3:拥有自己的缩微图制作工具
实现通常是利用/写入一个自定义程序放在WEB服务器上,利用一些浏览器来获取网站缩微图。具体过程如下:
设置一个写入工具接受请求为目标网址创建网页缩微图。
在你的WEB服务器上打开浏览器(隐藏进程)。
从浏览器获取网站缩微图并保存。
好处:
你不需要依赖任何人,安全自己控制。
速度快,因为你不需要去获得另一个服务器缩略图。
相对廉价的解决。
缩略图可以创造你想要的任何一页,上层、子页等.
能否收费服务
弊端
可能造成服务器高负荷。
可能有些不适应的HOSTINGS。
举办这类活动,费用较昂贵。

Website Image Creator 就是这类工具之一。

Website Thumb Generator can be used to create website thumbnails for your needs, or start your own website thumbnail generation service.


Requirements:

Windows hosting
PHP GD library (installed on most hostings)
Permissions to execute third-party applications (i.e. exe files)
Permissions to execute Internet Explorer

How it works:

Website Thumbnail Generator checks if it already has website image in the cache, and shows it in the browser.
If no cached image then IECapt would be run from the script.
IECapt would run Internet Explorer, grab full sized website screenshot from it, and save image into the folder you specified in script settings.
Then Website Thumbnail Generator would resize image, and show it in the browser.

Installation:

Download IECapt from http://iecapt.sourceforge.net or from our site: IECapt. Place it in some folder on your server.
Download Website Thumbnail Generator using link below, and unzip it to the same folder.
Update webthumb.php with your settings for thumbnails folder, cache time, default thumbnail size, etc.

Sample usage:

webthumb.php?url=http://www.microsoft.com
webthumb.php?url=http://www.thumbnails.com&x=150&y=150
Download Website Thumbnail Generator

Source: http://www.zubrag.com/articles/create-website-snapshot-thumbnail.php

2007年6月4日 星期一

開發進度

2007-06-05 implement
2007-06-04 set implement
2007-06-01 photo cut implement and imagemagick setup
2007-05-31 basic implement

NetBeans

Copy From 維基百科,自由的百科全書

開發者 Sun Microsystems
最新穩定版 NetBeans IDE 5.5 Release Candidate 2 / OCT 2006
作業系統 Cross-platform
類型 Java IDE
許可協議 CDDL
網站 www.netbeans.org
NetBeans是由Sun建立的開放源碼的軟體開發工具,是一個開放框架,可擴展的開發平臺,可以用於Java,C語言/C++等的開發,本身是一個開發平臺,可以通過擴展外掛程式來擴展功能。

在 NetBeans Platform 平臺中,應用軟體是用一系列的軟體模組(modular software components)建構出來。而這些模組是一個jar檔(Java archive file)它包含了一組Java程式的類別而它們實作全依據依 NetBeans 定義了的公開介面以及一系列用來區分不同模組的定義描述檔(manifest file)。有賴於模組化帶來的好處,用模組來建構的應用程序可只要加上新的模組就組就能進一步擴展。由於模組可以獨立地進行開發,所以由 NetBeans 平臺開發出來的應用程序就能利用著第三方軟體,非常容易及有效率地進行擴充。


歷史
NetBeans 始於1997年的Xelfi計劃,本身是捷克布拉格查理大學Charles University的數學及物理學院的學生項目。其後有公司開始就這個計劃而發展這個IDE項目。1999年昇陽電腦Sun Microsystems終於推出商用的IDE並名為 NetBeans。並在同年的7月公開源碼,直到現在 NetBeans 的社群依然持續增長,而且更多個人同企業來意使用 NetBeans 作為項目開發的工具。 [1]


NetBeans 平臺
NetBeans 平臺是一種可重複使用的框架用於簡化其他桌面應用程式的開發。當基於NetBeans 平臺的應用被執行,平臺主要類別的main方法便會被執行。可用的模組會被放安置在存儲器中,並且開始執行任務。通常模組會只在被需要時,其代碼才會被裝進記憶。

應用程式能動態安裝模組。任何應用程式能包括更新模組,允許用戶申請下載的應用程式升級和加入新功能。這樣安裝,升級以及新發並行不必迫使用戶每再次下載整個應用程式。

整個 Netbeans 平臺提供對桌面應用程式常用的服務,允許開發者集中於僅限於他的應用程式的邏輯設計。其中 NetBeans 平臺的主要特徵是︰

用戶界面管理 User interface management (例如 選單和工具條) 用戶設定管理 User settings management 存儲管理 Storage management(保留和裝任何種類數據) 視窗管理 Window management 術士框架 Wizard framework(一步一步支援對話框)


相關網站
官方網頁
官方中文網頁
Introduction to NetBeans Platform -- NetBeans Mobility Pack -- NetBeans Profiler -- NetBeans Enterprise Pack -- NetBeans C/C++ Pack
NetBeans Feature Demos (Flash movies)
Build Your RCP Application on the NetBeans Platform + RCP Tutorials
NetBeans Programming Tutorials: Swing GUIs, Web and Enterprise, Mobility, Profiling...
NetBeans GUI Builder "Matisse"
Blogs about NetBeans
NetBeans plugin catalogue and NB Extras to extend IDE functionality
NetbeansIDA-Interactive DisassemblerToDecompiler Netbeans module with Interactive Disassembler
Netbeans Archived User Forums

2007年5月29日 星期二

check class

class_exists :
if (class_exists('MyClass')) {
$myclass = new MyClass();
}

interface_exists
// Check the interface exists before trying to use it
if (interface_exists('MyInterface')) {
class MyClass implements MyInterface
{
// Methods
}
}

get_declared_classes
print_r(get_declared_classes());

exec() check

$command = escapeshellcmd($command);
//escapeshellcmd -- Escape shell metacharacters
exec($command)

POST 方法上傳

符合 RFC-1867 標準的瀏覽器
PHP 的這種特性使得我們既可以上傳文本文件,也可以上傳二進制文件。利用 PHP 的認証和文件操作函式,您就可以控制誰有上傳的權限,以及在文件上傳後進行哪些處理。

PHP 也支援 PUT 方法的文件上傳,Netscape Composer 和 W3C 的 Amaya 客戶端使用這種方法。

自動全域變數 $_FILES 從 PHP 4.1.0 版本開始被支援。在這之前,從 4.0.0 版本開始,PHP 支援 $HTTP_POST_FILES 陣列。這些陣列將包含所有關於您上傳的文件的訊息,其中,我們推薦您使用 $_FILES。

我們假設文件上傳字段的名稱如上例所示,為 userfile。


$_FILES['userfile']['name']
客戶端機器文件的原名稱。

$_FILES['userfile']['type']
文件的 MIME 型別,需要瀏覽器提供該訊息的支援,例如“image/gif”。

$_FILES['userfile']['size']
已上傳文件的大小,單位為字節。

$_FILES['userfile']['tmp_name']
文件被上傳後在伺服端儲存的臨時文件名。

$_FILES['userfile']['error']
和該文件上傳相關的錯誤代碼。['error'] 是在 PHP 4.2.0 版本中增加的。
UPLOAD_ERR_OK
值:0; 沒有錯誤發生,文件上傳成功。

UPLOAD_ERR_INI_SIZE
值:1; 上傳的文件超過了 php.ini 中 upload_max_filesize 選項限制的值。

UPLOAD_ERR_FORM_SIZE
值:2; 上傳文件的大小超過了 HTML 表單中 MAX_FILE_SIZE 選項指定的值。

UPLOAD_ERR_PARTIAL
值:3; 文件只有部分被上傳。

UPLOAD_ERR_NO_FILE
值:4; 沒有文件被上傳。


註: 這些在 PHP 4.3.0 之後變成了 PHP 常數。

在 PHP 4.2.0 以上版本,您還可以通過 $_FILES['userfile']['error'] 變數來根據不同的錯誤代碼來做相關的判斷。不管做何種的判斷,您必須將該文件從臨時目錄中刪除,要麼將其移動到其它的地方。

如果該文件沒有被移動到其它地方也沒有被改名,則該文件將在表單請求結束時被刪除。

2007年5月25日 星期五

foreach

$array = array("1"=>"a","2"=>"b","3"=>"c","4"=>"d","5"=>"e");
foreach($array as $key => $val){
$i = 1;
echo $i."@@".$val."
";
$i++;
}

Result:
1@@a
1@@b
1@@c
1@@d
1@@e

Group , Join

Group :
1. mysql_num_rows(user_group_34) = mysql_num_rows(efun_group) = 4
2. where only one rule , if wrong may make (Cartesian join)笛卡兒連接
=> 4*4 = 16 筆
SELECT G.s_name,U.memeber_id FROM user_group_34 U, efun_group G
WHERE U.group_id = G.id
GROUP By G.s_name

s_name member_id
group1 9
group2 9
group3 9
group4 9

Join
CROSS JOIN
 
兩個表格在結合時,不指定任何條件,如:
SELECT employee.realname, salary.amount FROM employee, salary
SELECT employee.realname, salary.amount FROM employee JOIN salary
SELECT employee.realname, salary.amount FROM employee CROSS JOIN salary
 在這個例子中,employee 原有 4 筆資料,而 salary 有 5 筆資料,在 JOIN 之後,結果將是兩者資料筆數的乘積:20。就等於是將兩個資料表中,所有可能的組合全部列出來一樣,其結果在實務上不見得有意義。這種結合可被視為兩個資料表的「笛卡兒乘積(Cartesian product)」。《執行結果》

INNER JOIN
 兩個表格在結合時,指定彼此之間的結合條件,如:
SELECT employee.realname, salary.amount FROM employee, salary
WHERE employee.employee_id = salary.employee_id
SELECT employee.realname, salary.amount FROM employee
JOIN salary ON employee.employee_id = salary.employee_id
SELECT employee.realname, salary.amount FROM employee
INNER JOIN salary ON employee.employee_id = salary.employee_id
 如此一來,只有符合結合條件(同時存在於彼此之間)的資料,才會被 JOIN 在一起。這是最常用的 JOIN 型式。《執行結果》

OUTER JOIN
 兩個表格在進行 INNER JOIN 時,只有彼此相符合的資料列才會被考慮到,除此之外,就完全被忽略了。相較於 INNER JOIN 的排他性,OUTER JOIN 則是「寬容」多了。
 在進行 LEFT OUTER JOIN 時,除了彼此相符合的資料列以外,左方的資料表中不相符的資料列也會被強迫輸出,如:
SELECT employee.realname, salary.amount FROM employee
LEFT OUTER JOIN salary ON employee.employee_id = salary.employee_id
SELECT employee.realname, salary.amount FROM employee
LEFT JOIN salary ON employee.employee_id = salary.employee_id
 像 Chuang 這種僅出現在 empolyee 裡,不存在於 saraly 中的資料列,在搭配 NULL 值之後,也能被列在結果之中了。善用這種特殊結果,我們可以順利找到只存在前一資料表,而不存在於後一資料表的資料列。《執行結果》

NATURAL JOIN
 NATURAL 又代表什麼?加上這個關鍵字之後,兩個表格在進行 JOIN 時,不必言明彼此的結合關係,兩者之間同名的欄位會被自動結合在一起。
 所以,以下兩段語法的執行結果相同:
SELECT employee.realname, salary.amount FROM employee
INNER JOIN salary ON employee.employee_id = salary.employee_id
SELECT employee.realname, salary.amount FROM employee
NATURAL JOIN salary
 以下兩段語法的執行結果也是相同的:
SELECT employee.realname, salary.amount FROM employee
LEFT JOIN salary ON employee.employee_id = salary.employee_id
SELECT employee.realname, salary.amount FROM employee
NATURAL LEFT JOIN salary

fetch query result

$sql = "SELECT * from user WHERE s_user_account = '".$account."'";
$query = $this->db->query($sql);

return $query ://只送回query的第一筆資料,需要搭配query->row_array()才能 praser出array
CI_DB_mysql_result Object ( [conn_id] => Resource id #25 [result_id] => Resource id #28 [result_array] => Array ( ) [result_object] => Array ( ) [current_row] => 0 [num_rows] => 0 )

return $query -> result: ://送回query的全部資料
Array (
[0] => stdClass Object ( [id] => 1 [member_id] => 9 [group_id] => 1 [s_role] => u [approver_id] => 8 )
//////////////////////////////////
[1] => stdClass Object ( [id] => 3 [member_id] => 9 [group_id] => 2 [s_role] => u [approver_id] => 8 )
[2] => stdClass Object ( [id] => 5 [member_id] => 9 [group_id] => 3 [s_role] => u [approver_id] => 8 )
[3] => stdClass Object ( [id] => 7 [member_id] => 9 [group_id] => 4 [s_role] => u [approver_id] => 8 )
)

return $query
$user = $query->row_array();
Array ( [id] => 9 [s_user_account] => windharry [s_password] => windharry [n_shard] => 1 [n_hash] => 34 [s_email] => windharry@mail.com [s_blog_title] => [d_create_time] => 2007-05-23 16:25:28 [d_update_time] => 2007-05-23 16:25:28 )

2007年5月23日 星期三

kkwi

http://news.chinatimes.com/Chinatimes/ExteriorContent/ChinatimesWeekly/newweekly-content/0,3813,170205+96051111,00.html

2007年5月22日 星期二

20070522 Mysql Driver 編碼問題

solution1:
強制指定編碼.

/systems/database/drivers/mysql/mysql_diver.php

function _execute($sql)
{
$sql = $this->_prep_query($sql);
@mysql_query('SET NAMES utf8', $this->conn_id);// add by Harry Yao 20070522
return @mysql_query($sql, $this->conn_id);
}

2007年5月21日 星期一

ignore_user_abort()

這函式似乎很少看到...
以前也沒用過
但今天用上了
事情是這樣發生的...

弄了一個空間
讓人用FTP上傳檔案
Web部分,作檔案瀏覽的介面
對於圖檔/視訊檔,作縮圖,並且視訊檔會轉成flv提供線上播放
作縮圖和轉flv都是
轉檔的動作都寫在thumb.php裡

用exec()執行外部程式再用ffmpeg從flv弄出jpg

但發現有的大一點的視訊檔
圖檔會生不出來
去翻存那些轉出來檔案的資料夾
發現只有flv

原因是
轉flv時轉檔轉太久
timeout後(或完成前使用者離開這一頁)browser放棄了,並告訴server不要檔案了
然後這個php沒執行完就被中斷了
所以弄出jpg檔的動作沒做到

後來用以下兩行解決
ignore_user_abort(true);
set_time_limit(0);

ignore_user_abort()可以讓php不會被中斷
於是一系列動作都會乖乖的執行完

=>
1.透過這函式應能寫出類似 crontab 的功能
2.發較大量信件的時候萬一使用或者瀏覽器中斷,發送動作還是會繼續做完.
mencoder
ffmpeg
imagemagick
之類的

其中視訊檔的縮圖,是先用
mencoder轉flv

換掉別人的網站首頁

可以用
圖層的概念.. 用一個長寬100%的div蓋掉原本的畫面



2007年5月20日 星期日

php

http://www.phppatterns.com/docs/design/archive/model_view_controller_pattern#the_controller

2007年5月15日 星期二

CakePHP使用手冊-命名規則?

轉貼自 http://www.ezluk.org/

是的,命名規則(convention)。從thefreedictionary:
可以查到Convention有幾個意思:




  1. General agreement on or acceptance of certain practices or
    attitudes: By convention, north is at the top of most maps.





  2. A practice or procedure widely observed in a group, especially
    to facilitate social interaction; a custom: the convention of
    shaking hands.





  3. A widely used and accepted device or technique, as in drama,
    literature, or painting: the theatrical convention of the
    aside.





Cake中的命名規則是讓魔法發生的關鍵,我們把它叫automagic。
不用說以命名規則進行一些設定有多好用,Cake甚至讓你的生產力提昇到驚人的等級,卻又不彈性。
Cake裡的命名規則既簡單又直觀。它是由web開發者多年來的實用經驗設計出來的。




第二節



檔名



檔名是由底線將文字分開。
一般規則中,名為MyNiftyClass的類別,存放的檔名就得叫my_nifty_class.php。



如果有看到一些Cake的程式片斷,自然就會知道:




  1. 如果有個Controller名叫KissesAndHugsController,
    那它的檔名叫一定叫kisses_and_hugs_controller.php
    (注意檔名內的_controller)





  2. 如果它的Model名稱叫OptionValue,
    那它的檔名一定是option_value.php。





  3. 若是個名叫MyHandyComponent的Component,
    那麼檔名就是my_handy.php(和controller不同,不需要加_component)。





  4. 若是個名為BestHelperEver的Helper,
    檔名一定是best_helper_ever.php。






第三節



Model





  1. Model的類別名稱是單數.





  2. Model的類別名稱,若只有一個單字則第一個字大寫,若由多個單字組成則每個單字第一個字母大寫。


    例如: Person, Monkey, GlassDoor, LineItem, ReallyNiftyThing





  3. 多對多Join資料表需命名為:
    第一個資料表複數_第二個資料表複數


    例如: tags_users





  4. Model的檔名用小寫加底線。


    例如: person.php, monkey.php, glass_door.php,
    line_item.php, really_nifty_thing.php






  5. Model對應的資料庫資料表同樣使用小寫加底線,但是用複數。
    Database tables related to models also use a lower-case
    underscored syntax - but they are plural.


    例如: people, monkeys, glass_doors, line_items,
    really_nifty_things


    譯註:person複數型原來是people!看來還是得懂些英文,難怪我用persons不行!






CakePHP的命名規則主要是要讓程式撰寫更流暢,提昇程式碼的可讀性。
如果你覺得它實在礙手礙腳,那就用自己的方法吧,Cake同樣也可以接受。
但得多做二件事:





  1. 定Model名稱: 在model定義中設定$name變數。





  2. 定Model對應的資料表:在model定義中設定$useTable變數







第四節



Controller





  1. Controller類別名稱是複數。





  2. Controller類別名稱如果只有一個單字則第一個字母大寫,若是多個單字則每個單字的第一個字母大寫。
    Controller類別名稱還必需在最後加上'Controller'。



    例如: PeopleController, MonkeysController,
    GlassDoorsController, LineItemsController,
    ReallyNiftyThingsController





  3. Controller檔名用小寫加底線,同樣必需在最後加上'_controller'字串。
    所以,如果有個controller叫PostsController,檔名就應該叫posts_controller.php



    例如: people_controller.php, monkeys_controller.php,
    glass_doors_controller.php, line_items_controller.php,
    really_nifty_things_controller.php





  4. protected成員函式,在函式名前加'-'。





  5. private成員函式,在函式名前加'--'。






第五節



View





  1. View由顯示他們的action名稱命名





  2. 將檔名命名為action名稱的小寫。



    例如: PeopleController::worldPeace() 需要一個view,檔名為
    /app/views/people/world_peace.thtml;
    MonkeysController::banana() 需要一個view,檔名
    /app/views/monkeys/banana.thtml.





也可以強制action使用某一個view,只要在action結束前呼叫$this->render('view檔名去除副檔名後的字串');。







第六節



Helper





  1. Helper類別名稱是以第一個字母大寫的單字組成,最後面再加上"Helper"字串。檔名則使用小寫加底線去除"helper"。



    例如: MyClarinetHelper放在/app/views/helpers/my_clarinet.php內。





在controller中引用的方式為:var $helpers = array('Html','MyHelper');。
接著就可以在view裡這麼呼叫:$myHelper->method().





第七節



Component





  1. Component類別名稱是以第一個字母大寫的單字組成,最後面再加上"Component"字串。檔名則使用小寫加底線去除"component"。



    範例: MyComponentComponent放在
    /app/controllers/components/my_component.php中









在controller內引用方式為:var $components array('MyComponent');。
接著在controller內呼叫$this->MyComponent->method()。





第八節



Vendor



Vendor沒有任何命名規則,原因很簡單:他們是第三方的程式碼,Cake對他們沒有控制權。


CakePHP使用手冊-暫存機制(Cache)

轉貼自 http://www.ezluk.org/

第一節



這是什麼?


從0.10.9.2378_final版之後,Cake開始支援view暫存(也叫全頁暫存)。
不,我們並沒有開玩笑。
你現在可以將layout和view暫時存放。
還可以將view的某部分標記,讓暫存機制忽略它。
這個功能如果巧妙應用,程式效能就能有效提昇。


當你送出一個URL時,Cake會先檢查這個URL在暫存資料內是否存在。
如果有,Cake就會直接將暫存版的資料回傳。
如果找不到,則動作就和一般沒二樣。


如果你已啟動Cake的暫存功能,Cake會把一般操作的輸出結果放在暫存空間內,讓未來的使用者使用。
下次網頁再被呼叫時,Cake就直接從暫存空間內將資料取出傳回。很棒吧!
讓我們仔細看看如何使用這個功能。



第二節



如何使用?



啟動暫存功能


預設,view暫存的功能是被關閉的。
要啟動它,首先需要更改/app/config/core.php檔內的CACHE_CHECK,由false改成true:



/app/config/core.php (部分)



define ('CACHE_CHECK', true);


這一行告訴Cake你要啟動View暫存功能。



在想要暫存的view的controller裡,必須將Cache helper加到$helpers陣列中





var $helpers = array('Cache');



接下來,就得指定要暫存的東西。




Controller變數$cacheAction


這一節,我們將教你如何告訴Cake要暫存什麼。
透過設定controller變數$cacheAction就可以做到。
$cacheAction要被設成陣列,內含想要暫存的action名稱,和想要保留的時間。
時間的指定必需是strtotime()能接受的字串(如'1 day' 或'60 seconds')。


假設我們有一個ProductsController,其中有一些東西想暫存。
以下的範例示範如何使用$cacheAction告訴Cake要暫時存放的東西為何。




$cacheAction 範例




//將最近常被流覽的產品網頁暫時存放六小時:

var $cacheAction = array(

    'view/23/'  => 21600,

    'view/48/'  => 21600

);

//暫存整個action。此例中會將rqcalled產品列表暫時存放一天:

var $cacheAction = array('recalled/' => 86400);

//如果想要,也可以將每一個action暫存起來,只要傳入一個時間字串:

//這個時間字串是strtotime()能接受的格式,表示存放的時間。

var $cacheAction = "1 hour";

//你也可以在某個action內定義暫存的內容,只要呼叫$this->cacheAction = array()...

   






標記View的內容


有時候,我們可能不想讓view內所有的內容都被暫存起來。
如果有些地方是用于展示新產品,你就會要Cake在暫存此頁時,不要將那一部分暫存。



要指定不被暫存的內容,只要將這些內容用<cake:nocache> </cake:nocache>標籤包起來即可。




<cake:nocache> 範例


<h1> New Products! </h1>

<cake:nocache>

<ul>

<?php foreach($newProducts as $product): ?>

<li>$product['name']</li>

<?endforeach;?>

</ul>

</cake:nocache>

 





清除暫存資料


首先要知道,如果資料庫有變更,Cake就會自動清除暫存資料。
例如,如果有個view用到Post model內的資訊,而Post曾被INSERT,UPDATE或DELETE過,Cake就會清除這個view的暫存資料。


但,有些狀況你會想自己清除某些暫存資料。
Cake也提供了clearCache()函式來做這件事,而它是全域函式:

clearCache() 範例


//清除名稱為'controller'的所有暫存網頁
clearCache('controller');

//清除名稱為'controller_action'的所有暫存網頁
clearCache('controller_action/');

//清除名稱為'controller_action_params'的所有暫存網頁
//註:可以有多個params
clearCache('controller_action_params');

//也可以用陣列一次清除多個網頁
clearCache(array('controller_action_params','controller2_action_params));





第三節



幾個要點


下面列出關於暫存功能的幾個要點:




  1. 設定 /app/config/core.php檔內的CACHE_CHECK啟動暫存功能。




  2. 在想要暫存的view的controller內,將Cache helper加到$helpers陣列中。




  3. 使用$cacheAction指定暫存的action。




  4. view裡不想被暫存的內容,用<cake:nocache> </cake:nocache>標籤包起來。




  5. 如果資料庫內容改變,Cake會自動清除有用到此內容的暫存資料。




  6. 使用clearCache()手動清除一些暫存資料。




CakePHP使用手冊-安全性元件(Security Component)

轉貼自 http://www.ezluk.org/

安全性元件(Security Component)


第一節



引言


Security component是用來避免controller action受到惡意或錯誤的request攻擊。
它讓你可以設定action可以被呼叫的條件,並可指定不合條件事如何處置。
同樣的,在使用Security component前,得先確定'Security'有出現在controller的$components陣列裡。



第二節



保護Controller的Action


Security component包含二個主要方法限制對controller action的使用權:





  • requirePost

  • string $action1

  • string $action2

  • string $action3...



特定的action必需透過POST呼叫才能執行。





  • requireAuth

  • string $action1

  • string $action2

  • string $action3...



比較POST過來的表單資料內的認証金鑰和存在使用者的session內的認証金鑰是否相同,如果相同就允許執行這個action。
這裡得注意一點,為了保有彈性,只有透過POST傳資料才會啟動作。
如果是由一般的GET request呼叫action,requireAuth()則不會有任何動作。
為了達到最高的安全性,你應該在想要完整保護的action內使用requirePost()強制使用POST,再用requireAuth()檢查金鑰。
第四節會再仔細說明認証金鑰是如何產生,如何消失。但先讓我們看個簡單的範例:



class ThingsController extends AppController

{

    var $components = array('Security');



    function beforeFilter()

    {

        $this->Security->requirePost('delete');

    }



    function delete($id)

    {

        //這個動作只有透過HTTP POST request才能執行

        $this->Thing->del($id);

    }

}

 


這兒,我們告訴Security component 'delete' action必需透過POST request才能執行。
通常我們會將告訴Security(和其他大部分的component)要怎麼做的程式放在beforeFilter()裡。
因為beforeFilter()會在action執行前被呼叫,接著立即執行action,這個時間點正是我們需要的。


你可以試著在流覽器內輸入這個action的URL,看看會發生什麼事。



第三節



處理非法的Request


所以,如果有個request不符合我們設定的安全需求,又會發生什麼事呢?
預設,這個request會變黑洞,client會收到404檔頭,應用程式立即中止。
然後,Security component還有個$blackHoleCallback屬性,讓你設定成定義在controller裡的回呼函式名稱。



除了單純給個404檔頭然後不做任何回應外,這個屬性可以讓你對此request做一些額外的檢查,
將它導向另一個位置,或甚至將對方的IP位置記錄下來。
然而,如果你選擇了使用回呼函式,那麼在request不合法時結束程式就完全是你的責任了。
如果回呼函式傳回true,否則Security component會繼續另一個檢查另一個安全需求。
否則,程式會停止檢查動作,繼續執行下面的行為,不會中止。



第四節



進階Request認証


requireAuth()函式允許你仔細的設定action可以從那兒執行與如何執行,但它同樣也有一些規定在,
在你了解認証動作的執行方法後就會明白。
如上述,requireAuth()是將POST資料與使用者的session資料內的認証金鑰相比較。
所以,所以在收到request和發出request的二個controller內都必需包含Sequrity component。



例如,如果有一個PostController的action,它的view內含表單會發出POST rquest呼叫CommentsController的action,
那麼,CommentsController和PostsController 都要包含Security component。



每次載入Security compoent時,即使它並沒有被用來保護任何action,都會做這些事:
首先,用核心的Security類別產生一個認証金鑰。接著,將這個金鑰寫到session裡,同時附上過期時間和額外的資訊(
過期時間可以在/app/config/core.php內的session安全設定中設定)。
然後,在隨之使用的controller內設定此金鑰。



接著,在view檔內任何使用$html->formTag()產生的表單標籤都會暗藏內含認証金鑰的輸入欄位。
在表單被POST時,Security component就可將此值與session裡的值(放在rquest最後面)比對。
隨後,認証金鑰會被重建,所有動作再重覆一次。


CakePHP使用手冊-要求處理元件

轉貼自 http://www.ezluk.org/

第一節



引言


RequestHandler component在Cake中被用來判定傳回的HTTP reqeust。
你可以用它通知controller有Ajax request,取得遠端client的IP位置和request種類,或去除不要的資料。
要使用RequestHandler component,得確認controller的$components陣列是否包含了這個component。



class ThingsController extends AppController

{

    var $components = array('RequestHandler');



    // ...

}


第二節



取得client/Request訊息


就讓我們開門見山,直接看函式說明:





  • accepts

  • string $type



依$type值傳回client接受的content-type。
如果$type等於null或沒有傳值,會傳回內含client能接受的所有content-type的陣列。
如果傳了一個字串過去,則會將$type拿去和content-type表(參考setContent())比對,若client可以接受這個種類時傳回true。
如果$type是一個陣列,每個字串會分別比對,如果其中一個能接受就傳回true。例如:



class PostsController extends AppController

{

    var $components = array('RequestHandler');



    function beforeFilter ()

    {

        if ($this->RequestHandler->accepts('html'))

        {

            // 當client接受HTML(text/html)時才執行這裡的程式

        }

        elseif ($this->RequestHandler->accepts('rss'))

        {

            // 當client接受RSS(application/rss+xml)時才執行這裡的程式

        }

        elseif ($this->RequestHandler->accepts('atom'))

        {

            // 當client接受atom(application/atom+xml)時才執行這裡的程式

        }

        elseif ($this->RequestHandler->accepts('xml'))

        {

            // 當client接受XML(application/xml 或 text/xml)時才執行這裡的程式

        }



        if ($this->RequestHandler->accepts(array('xml', 'rss', 'atom')))

        {

            // 當client接受XML,RSS,ATOM其中之一時才執行這裡的程式

        }

    }

}





  • getAjaxVersion




若使用Prototype JS 函式庫,它會在Ajax request上放置一段特殊表頭資料。
此函式可以傳回檔頭內記錄的Protytype版本資訊。





  • getClientIP




傳回client的IP位置。





  • getReferrer




傳回最出發出這個request的server名稱。





  • isAjax




如果目前的request是XMLHttpRequest就傳回true。





  • isAtom




如果client能接受Atom格式的內容則傳回true。





  • isDelete




若目前的request的'REQUEST_METHOD'等於DELETE則傳回true。





  • isGet




若目前的request的'REQUEST_METHOD'等於Get則傳回true





  • isMobile




如果HTTP_USER_AGENT說明了這是個手機的web流覽器則傳回true。





  • isPost




若目前的request的'REQUEST_METHOD'等於POST則傳回true





  • isPut




若目前的request的'REQUEST_METHOD'等於PUT則傳回true





  • isRss




若client能接受RSS格式的內容(application/rss+xml),則傳回true。





  • isXml




若client能接受XML格式的內容(application/xml 或 text/xml),則傳回true。





  • setContent

  • string $name

  • string $type



在content-type的別名表中加入一個選項,與accepts()和prefers()配合使用。
$name是別名名稱,$type則是MIME型別。
內建的幾種格式為:



// Name     => Type
'js' => 'text/javascript',
'css' => 'text/css',
'html' => 'text/html',
'form' => 'application/x-www-form-urlencoded',
'file' => 'multipart/form-data',
'xhtml' => array('application/xhtml+xml', 'application/xhtml', 'text/xhtml'),
'xml' => array('application/xml', 'text/xml'),
'rss' => 'application/rss+xml',
'atom' => 'application/atom+xml'



第三節



精簡資料


有時候我們會想刪除request或輸入的資料內部分內容。
下列的RequestHandler函式可以做這類的事。





  • stripAll

  • string $str



刪除$str內所有的空白,影像和script(就等於同時呼叫stripWhitespace(),stripImages()和stripScripts())。





  • stripImages

  • string $str



刪除$str裡的影像。





  • stripScripts

  • string $str



移除$str裡所有<script> 和<style> 相關的標籤。





  • stripTags

  • string $str

  • string $tag1

  • string $tag2...



移除$str裡$tag1,$tag2等參數指定的標籤。


$someString = '<font color="#FF0000"><bold>Foo</bold></font> <em>Bar</em>';



echo $this->RequestHandler->stripTags($someString, 'font', 'bold');



// 輸出: Foo <em>Bar</em>




  • stripWhiteSpace

  • string $str



移除$str內的空白字元。



第四節



其他好用的函式


當應用程式使用到AJAX技術時,RequestHandler component更會顯得特別好用。
setAjax()函式可以自動偵測AJAX的request,然後將controller的layout轉換成AJAX layout。
這樣的好處在於你可以做一個小視窗,在收到AJAX request時變大二倍。


// list.thtml

<ul>

<? foreach ($things as $thing):?>

<li><?php echo $thing;?></li>

<?endforeach;?>

</ul>



//-------------------------------------------------------------



//The list action of my ThingsController:

function list()

{

    $this->RequestHandler->setAjax($this);

    $this->set('things', $this->Thing->findAll());

}

 

當一般的流覽器呼叫/things/list時,沒排序的列表會被畫在應用程式預設的layout上。
但如果這是一個AJAX的rquest,列表就會自動被畫在AJAX layout上。


CakePHP使用手冊-資料過濾

轉貼自 http://www.ezluk.org/

資料過濾


第一節



程式中使用Sanitize


Cake內建的Sanitize類別是用來防止使用者傳送惡意攻擊資料或其他不想要的資料。
Sanitize是核心函式庫的一部分,所以可以在程式中任何一個地方使用,但最好是在controller或model裡使用。



// 首先,把核心函式庫包含進來:

uses('sanitize');

// 接下來,建立Sanitize物件:

$mrClean = new Sanitize();

// 從這裡開始就可以使用Sanitize清除資料

// (下節會介紹Sanitize類別中可以使用的方法)



第二節



讓資料安全地在SQL和HTML裡使用


這一節會說明如何使用Sanitize類別所提供的一些函式。





  • paranoid

  • string $string

  • array $allowedChars



此函式會將$string裡非文字的資料去除。
然而,你也可以把想要保留的字元放在$allowedChars陣列裡。



$badString = ";:<script><html><   // >@@#";

echo $mrClean->paranoid($badString);

// 輸出: scripthtml

echo $mrClean->paranoid($badString, array(' ', '@'));

// 輸出: scripthtml    @@




  • html

  • string $string

  • boolean $remove = false



這函式幫你將使用者提交的HTML資料以純文字的模式直接顯示在既存的HTML layout上。
當不想讓使用者破壞你的layout或在blog的文章內插入影像或script時特別有用。
如果$remove設成true,所有的HTML標籤都會被刪除,而不是直接把HTML檔字串看列印。



$badString = '<font color="#FF0000">HEY</font>';

echo $badString;

//輸出:HEY

echo $mrClean->html($badString);

// 輸出: <font color="#FF0000">HEY</font>

echo $mrClean->html($badString, true);

// 輸出: font color=#FF0000 HEY font





  • sql

  • string $string



將SQL指令脫逸(加上斜線),讓SQL指令被指為一般文字處理。
處理方法依系統magic_quotes_gpc 變數的設定值決定。





  • cleanArray

  • array @$dirtyArray



這個函式的功能十分強大,是個多功能的清理器,可以用於整個陣列上(如$this->params['form'])。
這函式傳入一個陣列,然後將它清理一翻:沒有傳回值,因為直接傳入參照。
下面的清理動作會作用在陣列內每個元素上(遞迴):




  1. 奇怪的空格(包含0xCA)會被用一般的空格取代




  2. HTML字串會被用正確的HTML標籤取代(如\n 換成 <br>).




  3. 再次檢查特殊字元,移除換行字元,增進SQL的安全性。




  4. 為SQL指令加上斜線(和上頭的sql函式一樣)。




  5. 把使用者輸入的反斜線換成可信任的反斜線。




CakePHP使用手冊-Session元件(Session Component)

轉貼自 http://www.ezluk.org/

Session元件(Session Component)


第一節



Cake內Session的儲存參數


Cake內建三種方式存放session資料:放在暫存檔,使用PHP預設機制,或存放在資料庫,預設使用PHP預設機制。
如果想改成使用暫存檔或資料庫,請編輯核心設定檔:/app/config/core.php。
依需要可以把CAKE_SESSION_SAVE變數改成'cake','php'或'database'三者之一。



core.php Session 設定


/**

 * CakePHP includes 3 types of session saves

 * database or file. Set this to your preferred method.

 * If you want to use your own save handler place it in

 * app/config/name.php DO NOT USE file or database as the name.

 * and use just the name portion below.

 *

 * Setting this to 'cake' will save files to /cakedistro/tmp directory

 * Setting it to 'php' will use the php default save path

 * Setting it to 'database' will use the database

 *

 *

 */

define('CAKE_SESSION_SAVE', 'php');


為了要將session資料存在資料庫,必須在資料庫內建立資料表。
資料表的schema放在/app/config/sql/sessions.sql內。



第二節



使用Cake的Session Component


Cake的session component用來與session資料互動。
它包含了對session資料最基本的讀寫動作,還包含錯誤訊息和接受訊息(如"Your data has been saved")等。
在所有的controller裡預設是可以使用Session component的。





  • check

  • string $name



檢查$name是否已經存於session裡。





  • del

  • string $name




  • delete

  • string $name



刪除$name這個session變數。





  • error




傳回Session component內所發生最後一個錯,常用於除錯。





  • flash

  • string $key = 'flash'



傳回session內用setFlash()所設定的最後一個訊息。
如果有指定$key,則會選用以該鍵存放的訊息中最近的一條。





  • read

  • string $name



傳回名為$name的session變數。





  • renew




建立新的session ID,重新目前使用中的session,刪除舊的,並將刪session的資料傳給新的。





  • setFlash

  • string $flashMessage

  • string $layout =
    'default'


  • array $params

  • string $key = 'flash'



將$flashMessage寫到session內(稍後可由flash()取得)。


如果$layout設成'default',訊息會以'<div class="message">'.$flashMessage.'</div>'型式儲存。
如果$layout設成'',訊息會原封不動的被存放。
如果設成其他值,則使用$layout指定的方式存放。


$params是留著未來使用的,目前沒有作用。


$key則可以讓這個訊息以$key鍵存放,呼叫flash()時可依不同鍵取回訊息。





  • valid




如果session有效則傳回true。
最好在read()前使用,以確認讀得到資料。





  • write

  • string $name

  • mixed $value



將名稱為$name,值為$value的session變數存放於目前的session中。


CakePHP使用手冊-權限控制表(ACL)

轉貼自 http://www.ezluk.org/

權限控制表(ACL)


第一節



了解ACL運作方式


大部分強大又重要的東西都需要一些權限控制。
權限控制表是一種分級明確又好管理的權限控制方式。
權限控制表(或簡稱ACL)主要管理二種事物:需要使用服務的事物,和被控制的事物。
以ACL的角度看,需要使用服務的事物(通常是使用者)叫access request object,簡稱ARO。
而系統內被控制的事物(通常是action或資料)叫access control object,簡單ACO。
每一個對象被稱為一個物件(object),因為有時候這些對象並不是人-有時候可能是程式中另一部分的邏輯。
ACO可以是任何你想要控制的東西,從controller的action 到一項web service,甚至是你祖母的線上日記裡的一行文字。


用一句話來說明這三個簡稱:ACL是用來決定ARO是否可以使用ACO的規範。



為了讓你更加了解這個概念,讓我們舉個實用的例子。
一群魔戒中的勇者們共同使用一組電腦系統。隊長必須在努力衝次任務的同時,在成員間守住一定程度的秘密與安全性。
ARO包含下面幾位:



Gandalf
Aragorn
Bilbo
Frodo
Gollum
Legolas
Gimli
Pippin
Merry

這些是系統中會要求使用服務的使用者(ARO),他們要使用的東西就是ACO。
這裡可以注意到,ACL並不是一種使用者認証系統。
你應該早有另一套存放使用者資料,並在他們進入系統時確認身份的方法。
在確認道使用者身份之後,才是ACL 站出發揮功用的時機。好,話題回到我們的勇者們身上。



Gandalf下一步得做的事是列出系統要管理的物品列表(ACO)。看起來會像這樣:



Weapons
The One Ring
Salted Pork
Diplomacy
Ale

傳統的方法裡,系統會用矩陣的方式管理,矩陣中顯示使用者與各物品間的使用權限。
若將這些資料成列成表,看起來就像下面所示,'X'表示拒絕存取,'O'表示允許存取:




Weapons The One Ring Salted Pork Diplomacy Ale
Gandalf X X O O O
Aragorn O X O O O
Bilbo X X X X O
Frodo X O X X O
Gollum X X O X X
Legolas O X O O O
Gimli O X O X X
Pippin X X X O O
Merry X X X X O

這樣的設計,看起來很完善。既可以保守機密(只有Frodo可以拿到魔戒),又可以防止意外發生(哈比人碰不到肉乾)。
權限似忽設計的很好,也很容易看得懂,對吧?



對這麼一個小系統而言,矩陣的的設定方式也許已經足夠。
但面對會慢慢變大的系統或系統裡有一大堆資源(ACO)和使用者(ARO)時,就無法這麼輕易的建立這個表了,比如說要為每個單位分配使用上百個營地。
矩陣的另一個缺點是無法真的為使用者分組,或依不同的組別給與不同的權限。
例如,我們想在戰爭結束後解除哈比人對酒和肉乾的禁令:
若只能分別更改每個使用者的權限,不但要改的項目很多,出錯的機率也非常高;若有辦法直接更改'哈比人'這一組的權限,一切就簡單多了。



ACL 以樹狀結構進行設計,通常會有一棵ARO的樹和一棵ACO的樹。
把物件整理成樹狀圖,不但可以做細部的設定,還可以以巨觀的方式管理。
身為一個叡智的領導者,Gandalf選擇在新系統中使用ACL,把他的物件整理如下:




Fellowship of the Ring
Warriors
Aragorn
Legolas
Gimli
Wizards
Gandalf
Hobbits
Frodo
Bilbo
Merry
Pippin
Vistors
Gollum

將我們的團隊以這種方式整理之後,便可以對這棵樹的每個結點定義使用權限了。
預設的權限是所有東西都不能使用,接者向下層一項一項權限開放。
最後開放的一定是最在意的事物。所以,依據ARO樹,Gandalf把權限如此設計:



Fellowship of the Ring: [Deny: ALL]
Warriors [Allow: Weapons, Ale, Elven Rations, Salted Pork]
Aragorn
Legolas
Gimli
Wizards [Allow: Salted Pork, Diplomacy, Ale]
Gandalf
Hobbits [Allow: Ale]
Frodo
Bilbo
Merry
Pippin
Vistors [Allow: Salted Pork]
Gollum

若想透過ACL 看看Pippin是否可以拿到Ale,首先查出他在樹中的路徑是Fellowship->Hobbits->Pippin。
然後看看每個節結的權限,其中對Pippin最明確的設定就是我們想得知的答案。




  1. Fellowship = DENY Ale,所以不允許(因為被設成所有東西都不允許)




  2. Hobbits = ALLOW Ale,所以允許




  3. Pippin = ?; 這裡沒有做任何特別的設定。




  4. 最終結論:允許使用ale。




我們還可以透過這棵樹對更底層做更細節的設定,變更上層的設定:



Fellowship of the Ring: [Deny: ALL]
Warriors [Allow: Weapons, Ale, Elven Rations, Salted Pork]
Aragorn [Allow: Diplomacy]
Legolas
Gimli
Wizards [Allow: Salted Pork, Diplomacy, Ale]
Gandalf
Hobbits [Allow: Ale]
Frodo [Allow: Ring]
Bilbo
Merry [Deny: Ale]
Pippin [Allow: Diplomacy]
Vistors [Allow: Salted Pork]
Gollum

你可以發現,Aragorn的權限雖然和所屬的Warrior組一樣,但仍可以單獨給他特別的權限。
再說明一次,我們把預設權限設成DENY,然後一層層向下,將想開放的設回ALLOW。
想看看Merry是否可以拿到Ale,先查一下Merry在這棵樹的路徑為:Fellowship->Hobbits->Merry,
然後查出每個節點所設與ale相關的權限:




  1. Fellowship = DENY 因為設定為全部拒絕




  2. Hobbits = ALLOW: ale, 所以允許




  3. Merry = DENY ale, 所以拒絕




  4. 最終結論:不能使用ale。





第二節


定義權限:Cake的INI型ACL


Cake的第一套ACL系統是透過存於Cake安裝設定裡的INI檔進行設定。
雖然它既實用又穩定,我們還是建議您使用以資料庫為基礎的ACL,最大原因是它可以動態建立ACO和ARO。
舊的ACL(ini版)在簡單的應用中還是非常好用,特別是對那些不想使用資料庫的人而言。



ARO/ACO的權限被定義在
permissions are specified in/app/config/acl.ini.php中。
使用的設定指定可以在acl.ini.php檔的開頭找到說明:


; acl.ini.php - Cake ACL 設定

; ----------------------------------------

; 使用這個檔案指定使用者權限

; aco = access control object (系統裡的某樣事物)

; aro = access request object (需要使用服務的某樣事物)

;

; 使用者資料加入方法如下:

;

; [使用者名稱]

; groups = group1, group2, group3

; allow = aco1, aco2, aco3

; deny = aco4, aco5, aco6

;

; 群組資料加入方法也差不多:

;

; [群組名稱]

; allow = aco1, aco2, aco3

; deny = aco4, aco5, aco6

;

; allow, deny, 和 groups 都可以省略。

; 注意:群組名稱千萬*不可以*和使用者名稱相同!!

; ACL 權限檢查順序如下:

; 1. 檢查使用者不允許的(如果找到穩合的,就決定不允許)

; 2. 檢查使用者允許的(的(如果找到穩合的,就決定允許)

; 3. 看看使用者屬於那些群組

; 4. 檢查群組不允許的(如果找到穩合的,就決定不允許)

; 5. 檢查群組允許的(如果找到穩合的,就決定允許)

; 6. 如果全部都沒找到,則決定不允許


這INI檔可用來定義使用者(ARO)所屬的群組與權限,也可用於定義群組的權限。


譯註:原文要大家去11.4節找更詳細的資料,不過譯者沒找到。乾脆直接把在acl.ini.php檔發現的說明文字放進來讓大家參考。



第三節


定義權限:Cake的資料庫型ACL



開始


ACL權限資料預設存放於資料庫中。資料庫型ACL(或叫dbACL)含有一組核心model,和可由命令列執行的script。
這model用來與資料互動,存放與讀取ACL的樹狀資料。
命令列的script則幫你開個頭,讓你在一開始學習就能和這棵樹互動。



一開始,你必需確定/app/config/database.php有存在,且設定正確。
對於一個剛剛安裝好的Cake系統來說,分辨這件事最容易的方法就是用web流覽器連到安裝目錄。
在這一頁最上方應該會看到"Your database configuration file is present."和"Cake is able to connect to the database."。
如果有錯誤,請參考4.1節,會教您如何設定資料庫。



接著,使用ACL命令列script將資料庫初始化,以便儲存ACL資料。
/cake/scripts/acl.php這支script可以幫助完成這件事。
在/cake/scripts/目錄下執行以下的命令:


使用acl.php將資料庫初始化


$ php acl.php initdb



Initializing Database...

Creating access control objects table (acos)...

Creating access request objects table (acos)...

Creating relationships table (aros_acos)...



Done.



此時,在這個專案的資料庫中應該可以看到新的資料表。
如果你對Cake建立的樹狀資料感到好奇,可以打開資料庫看個清楚。
基本上,它存放的是各節點與節點在樹中的位置。
而acos和aros資料表則存放與他們相關的節點,aros_acos資料表則將aros和acos連結起來。



現在,你可以開始建立自己的ARO和ACO樹了。



建立ARO和ACO


有二種方法取用某個ARO或ACO。
其一是指定一個數字的id,而這個數字通常就是資料表的主鍵。
另一個方法是指定一個字串別稱。
這二種方法並不是互斥的。



建立ARO的方法是使用Aro model裡的方法。
Aro類別的create()方法有三個參數:$link_id,$parent_id,和$alias。
這個方法會在$parent_id下建立新的ACL物件,如果$parent_id是null,則表示這是個根物件。
$link_id則可以將使用者物件連結到ACL結構內。
$alias則可以讓你透過別名取用ARO物件,而不是沒意義的數字。


在建立ACO和ARO之前,必需先載入這些類別。
最簡單的方法是在controller裡使用$components陣列把ACL component包含進來使用:


var $components = array('Acl');

完成之後,讓我們看看建立這些物件的程式看起來是什麼樣子。
以下的程式碼可以放在controller action的任何地方:


$aro = new Aro();



// 首先,建立幾個ARO

// 這些物件的父層一開始並沒有東西



$aro->create( 1, null, 'Bob Marley' );

$aro->create( 2, null, 'Jimi Hendrix');

$aro->create( 3, null, 'George Washington');

$aro->create( 4, null, 'Abraham Lincoln');



// 現在,建立幾個群組將這些使用者組織起來:

// 注音,這些物件的ID是0,因為他們永遠不會代表系統內任何一個使用者。



$aro->create(0, null, 'Presidents');

$aro->create(0, null, 'Artists');



//再來,把所有的ARO與相對的群組連起來:



$aro->setParent('Presidents', 'George Washington');

$aro->setParent('Presidents', 'Abraham Lincoln');

$aro->setParent('Artists', 'Jimi Hendrix');

$aro->setParent('Artists', 'Bob Marley');



//簡而言之,建立ARO的方法如下:

$aro = new Aro();

$aro->create($user_id, $parent_id, $alias);

你也可以在命令列模式下用$acl.php create aro <link_id> <parent_id>
<alias>
這個script建立ARO。


ACO的建立方法也類似:


$aco = new Aco();



//建立一些ACO物件

$aco->create(1, null, 'Electric Guitar');

$aco->create(2, null, 'United States Army');

$aco->create(3, null, 'Fans');



// 要為這些物件建立群組,可以使用setParent(),在這個範例如就不示範了。



//所以,建立ACO的方法為:

$aco = new Aco();

$aco->create($id, $parent, $alias);

命令列模式下的script:


$acl.php create aco <link_id> <parent_id>
<alias>




指定權限


建立ACO和ARO後,我們終於可以開始指定二個群組間的權限了。
負責做這件事的,是Cake的核心Acl component。
繼續我們剛剛的範例:


// 首先,我們必需在controller裡使用Cake的ACL component



class SomethingsController extends AppController

{

    // 宣告對Acl component的使用權



    var $components = array('Acl');



    // 記得:ACL在沒有任何資訊的情況下,預設是拒絕所有的事。

    // 所有的存取動作都會被禁止。讓我們對ARO開啟一些對ACO的

    // 存取權限。



    function someAction()

    {

        // 允許



        // 這兒是給予ARO對ACO完整控制權的地方

        $this->Acl->allow('Jimi Hendrix', 'Electric Guitar');

        $this->Acl->allow('Bob Marley',   'Electric Guitar');



        // 我們也可以對群組指配權限,記得嗎?

        $this->Acl->Allow('Presidents', 'United States Army');



        // allow()方法其實有第三個參數,$action。

        // 可以使用這個參數只指定部分存取功能。

        // $action可以設成create, read, update 或 delete。

        // 如果沒有指定,則假設全部一起指定。



        $this->Acl->allow('George Washington', 'Electric Guitar', 'read');

        $this->Acl->allow('Abraham Lincoln',   'Electric Guitar', 'read');



        // 拒絕



        // 設定拒絕的方法和上面類似:

        $this->Acl->deny('Abraham Lincoln', 'United States Army');





    }

}

 

這麼一個特殊的範例也許沒什麼特別的功用,但它可以向您展示整個流程。
把Acl component和使用者管理的controller合在一起使用最有用。
當系統建立了一個使用者,他的ARO可以同時被建立,並放在正確的節點上。
接著依他的狀況將權限設到某個ACO或ACO群組上。


權限也可以在命令列下透過script指派。
語法和model裡的函式類似,若實在不懂,直接執行$php acl.php help也會列出使用方法。




第四節


檢查權限:ACL Component


檢查權限是使用Cake ACL裡最簡單的一部分:只有一個函式,check()。
在AppController的某個地方進行ACL檢查是個不錯的主意,只要放在那兒,
就可以在應用程式的任何地方進行權限檢查。下面的個範例:


class AppController extends Controller

{

    // 取得component

    var $components = array('Acl');



    function checkAccess($aco)

    {

        // 使用component檢查權限

        $access = $this->Acl->check($this->Session->read('user_alias'), $aco, $action = "*");



        //拒絕存取

        if ($access === false)

        {

            echo "access denied";

            exit;

        }

        //允許存取

        else

        {

            echo "access allowed";

            exit;

        }

    }

}

基本上,只要讓Acl component在AppController裡可以使用,應用程式的其他地方就都可以使用。


// 這是基本的呼叫法:

$this->Acl->Check($aro, $aco, $action = '*');


CakePHP使用手冊-插件(Plugin)

轉貼自 http://www.ezluk.org/

插件(Plugin)



CakePHP允許您將一堆model,controler和view打包在一起,讓別人以plugin的方式使用在自己的CakePHP應用程式裡。
有一個很棒的使用者管理模組?簡單的blog?或是好用的web service模組?將它們打包成CakePHP plugin,放到別人的應用程式裡吧。



應用程式和安裝的plugin間最主要的連繫在於應用程式的設定(資料庫連結設定等)。
除此之外,它在自己的小空間內運作,就好像只有自己是獨立的應用程式一樣。



第一節


建立Plugin



讓我們示範建立一個新的plugin,功能是訂pizza。還有什麼功能比這個範例更有用的呢?
開始吧,我們必需先在/app/plugins目錄內建立一個子目錄,準備將plugin 的檔案放在裡頭。
這個子目錄的名稱相當重要,會被用在很多地方,所以選一個好名字吧。
對這個範例來說,就讓它叫'pizza'好了。
最後目錄結構看起來會像這樣:




定Pizza plugin的目錄結構



/app
/plugins
/pizza
/controllers <- plugin controllers 放這兒
/models <- plugin models 放這兒
/views <- plugin views 放這兒
/pizza_app_controller.php <- plugin的 AppController,依據plugin的名字命名
/pizza_app_model.php <- plugin的 AppModel,依據plugin的名字命名



一般的應用程式不需要定義AppController和AppModel,但是plugin需要。
必需建立它們,plugin才會正常運作。
這二個特殊的類別是根據plugin的名字來命名,類別繼承自AppController和AppModel類別。
它們看起來像這樣:




Pizza Plugin AppController:
/app/plugins/pizza_app_controller.php



<?php



class PizzaAppController extends AppController

{

    //...

}



?>




Pizza Plugin AppModel: /app/plugins/pizza_app_model.php



<?php



class PizzaAppModel extends AppModel

{

    //...

}



?>



如果你忘了定義這二個特別的類別,CakePHP會送你一個"Missing Controller"錯誤。




第二節


Plugin的Controller



我們這個pizza plugin的controller會存放在/app/plugins/pizza/controllers。
既然我們主要想追踪的是pizza訂單,那就得要有一個OrdersController。




雖然不是絕對必要,但我們還是強烈建議,plugin裡的controller最好取相對唯一的名稱,以免與使用的應用程式相衝。
其他程式內也非常可能會用UsersController,OrderController或ProductController等名稱:
所以你對controller的命名可能需要多一點創意,或把plugin的名稱當作類別的前置詞(像PizzaOrdersController)。




所以,我們把新的PizzaOrdersController放在/app/plugins/pizza/controllers裡,看起來像這樣:




/app/plugins/pizza/controllers/pizza_orders_controller.php



<?php



class PizzaOrdersController extends PizzaAppController

{

    var $name = 'PizzaOrders';



    function index()

    {

        //...

    }



    function placeOrder()

    {

        //...

    }

}



?>



注意這個controller是繼承plugin的AppController(叫PizzaAppController)而不是上層應用程式的AppController。




第三節


Plugin的Model



plugin的Model存放在/app/plugins/pizza/models目錄內。
我們已經為這個plugin定義了一個PizzaOrdersController,讓我們為這個controller建一個model,叫PizzaOrder(
類別名稱PizzaOrder有依我們的命名規則命名,也夠獨特,所以就讓它叫這個名字吧)。




/app/plugins/pizza/models/pizza_order.php



<?php



class PizzaOrder extends PizzaAppModel

{

    var $name = 'PizzaOrder';

}



?>



同樣的,這個類別繼承自PizzaAppModel而不是AppModel。




第四節


Plugin的View



View的行為和一般的應用程式一模一樣。只要將他們放在/app/plugins/[plugin]/views/目錄內。
對我們這個訂pizza的plugin來說,最少需要一個view對應PizzaOrdersController::index() action,檔名和目錄位置像這樣:




/app/plugins/pizza/views/pizza_orders/index.thtml



<h1>Order A Pizza</h1>

<p>Nothing goes better with Cake than a good pizza!</p>

<!-- An order form of some sort might go here....-->




第五節


使用plugin



現在你已經備妥一切,可以準備發布(這時,我們會建議再多一些額外的資料,如說名檔,SQL檔等)。



plugin被安裝在/app/plugins後,就可以透過URL /pluginname/controllername/action存取。
在訂pizza的範例中,就可以在/pizza/pizzaOrders 存取到PizzaOrdersController。



以下是在CakePHP中使用plugin的一些注意事項:





  1. 如果[Plugin]AppController和[Plugin]AppModel不存在,在嘗試存取plugin controller時,
    會得到"Missing Controller"的錯誤訊息。





  2. 可以用plugin的名字做一個預設的controller。
    如果有做這個controller,就可以透過/[plugin]/action存取。
    例如,有個叫'users'的plugin,內含名為UsersController的controller,就可以透過/users/add取用add這個action。
    但要確定沒有另一個叫AddController controller被放在[plugin]/controllers目錄內。


    譯註:存取users plugin的AddController的URL也是/users/add/[action]





  3. Plugin預設使用/app/views/layouts目錄下的layout。





  4. 可以在controller內使用$this->requestAction('/plugin/controller/action');與plugin進行內部溝通。




  5. 使用你使用requestAction,請確認controller和model名稱盡可能唯一。
    否則PHP就會送你一個"redefined class ..."的錯誤。





特別感謝Felix Geisendorfer提供本章節的內容。


CakePHP使用手冊-資料檢驗

轉貼自 http://www.ezluk.org/

資料檢驗



第一節


資料檢驗



建立自訂的資料檢驗規則可以協助確認Model裡資料是否合乎企業邏輯的需求,
例如密碼長度只能八個字元,使用者名稱字能使用文字等等。



資料檢驗的第一步是在Model裡建立檢驗規則。
這件事可透過定義Model裡的Model::validate陣列達成,例如:




/app/models/user.php



<?php

class User extends AppModel

{

   var $name = 'User';



   var $validate = array(

      'login' => '/[a-z0-9\_\-]{3,}$/i',

      'password' => VALID_NOT_EMPTY,

      'email' => VALID_EMAIL,

      'born' => VALID_NUMBER

   );

}

?>



檢驗規則定義法是使用Perl相容的通用表示法,有些常用的規則已事先定義在/libs/validators.php。如:




  • VALID_NOT_EMPTY


  • VALID_NUMBER


  • VALID_EMAIL


  • VALID_YEAR



若model定義了$validate陣列,檢驗動作便會在資料儲存前自動啟動(呼叫Model::save()時)。
若想要手動啟動檢驗功能,
也可以直接呼叫Model::validates()(如果資料錯誤會傳回false)和Model::invalidFields()(傳回存有錯誤訊息的陣列)。



但通常資料都隱藏在controler的程式裡。
下面的範例示範如果使用檢驗的機制:




/app/controllers/blog_controller.php 內處理表單資料的Action



<?php

class BlogController extends AppController {



   var $uses = array('Post');



   function add ()

   {

      if (empty($this->data))

      {

         $this->render();

      }

      else

      {

         if($this->Post->save($this->data))

         {

             //太好了,資料合乎規則

         }

         else

         {

            //危險,威爾羅賓遜!檢驗結果錯誤。

            $this->set('errorMessage', 'Please correct errors below.');

            $this->render();

         }

      }

   }

}

?>




這個action使用的view看起來可以像這樣:





在/app/views/blog/add.thtml加入表單的view


<h2>Add post to blog</h2>

<form action="<?php echo $html->url('/blog/add')?>" method="post">

    <div class="blog_add">

        <p>Title:

            <?php echo $html->input('Post/title', array('size'=>'40'))?>

            <?php echo $html->tagErrorMsg('Post/title', 'Title is required.')?>

        </p>

        <p>Body

            <?php echo $html->textarea('Post/body') ?>

            <?php echo $html->tagErrorMsg('Post/body', 'Body is required.')?>

        </p> 

        <p><?=$html->submit('Save')?></p>

    </div>

</form>

         



Controller::validates($model[, $model...])可用來啟動model裡自訂的檢驗規則。
Controller::validationErrors()則傳回model丟出的錯誤訊息,然後用tagErrorMsg()顯示於view內。



如果你想要設計些正規表示法無法表示的檢驗規則,可以使用model的invalidate()函式將某一欄位標示為錯誤。
例如我們想要在使用者要建立的使用者名稱已存在時,在表單上顯示錯誤訊息。
由於單單使用正規表示法很難表示這樣的規則,我們必需自己另外設計這個邏輯,接著把這個欄位標示為錯誤,
再經由Cake一般處理的流程處理。controller看起來像這樣:



<?php



class UsersController extends AppController

{

    function create()

    {

        // 來查是否有提交表單資料

        if (!empty($this->data['User']))

        {

            //看看這位使用者的姓名是否存在

            $user = $this->User->findByUsername($this->data['User']['username']);



            // 將欄位標示為錯誤,觸發HTML Helper的錯誤訊息。

            if (!empty($user['User']['username']))

            {

               //產生tagErrorMsg('User/username')

               
$this->User->invalidate('username');

            }



            //試著儲存資料,如果有錯就不要做。

            if($this->User->save($this->data))

            {

                $this->redirect('/users/index/saved');

            }

            else

            {

                 $this->render();

            }

        }

    }

}



?>

 

CakePHP使用手冊-全域函式與常數

轉貼自 http://www.ezluk.org/

全域函式與常數


本章列出一些使用Cake開發應用程式時常用到的全域函式與常數。



第一節


全域函式



這兒列出的是Cake裡每個地方都可以使用的函式。
其中有很多是為了包裝名字很長的PHP函式而設計(包裝型函式),當你想要短小精幹的函式為你重覆做一些事,那這就是你要的。
還有些(像vendor()和uses())可以用來引用(include)外部程式碼,或執行其他函式。


譯註:接下來會用"包裝型函式"代表Wrapper,此類的函式內容就是把所有的參數轉去呼叫另一個函式,
主要目的是減短函式名稱。




  • config


載入Cake的核心設定檔,如果成功的話就傳回true。



  • uses


  • string $lib1


  • string $lib2...




用來載入Cake的核心函式庫(放在cake/libs/)目錄內)。
用不含副檔名'.php'的函式庫檔名指定。



uses('sanitize', 'security');



  • vendor


  • string $lib1


  • string $lib2...




載入第三方函式庫(放在/vendors目錄內)。
用不含副檔名'.php'的函式庫檔名指定。



vendor('myWebService', 'nusoap');



  • debug


  • mixed $var


  • boolean $showHtml = false




如果應用程式的DEBUG層級不是0,就把$var字串印出。
如果$showHtml是true,URL資料會以流覽器視為字串的格式輸出。


譯註:如果$showHtml是true,'<'為被以'%lt;'取代,'>'會以’%gt;'取代。




  • a


傳回包裝型函式使用的參數陣列。


譯註:原始碼中的註解為:傳回內容存著傳入參數的陣列。例如: a('a', 'b')傳回 array('a', 'b')。



function someFunction()

{

    echo print_r(a('foo', 'bar'));

}



someFunction();



// output:



array(

    [0] => 'foo',

    [1] => 'bar'

)




  • aa






傳回包裝型函式使用的關聯式陣列


譯註:原始碼中的註解為:由傳入的參數建立關聯式陣列。例如:aa('a','b')傳回 array('a'=>'b')。



echo aa('a','b');


// 輸出:


array(

    'a' => 'b'

)




  • e


  • string $text




ehco()函式的包裝型函式。





  • low






strtolower()函式的包裝型函式。





  • up






strtoupper()函式的包裝型函式。





  • r


  • string $search


  • string $replace


  • string $subject




str_replace()函式的包裝型函式。





  • pr


  • mixed $data




便利的函式,功能和下列的程式相同:



echo "<pre>" . print_r($data) . "</pre>";

只有在DEBUG設為非零時才會把資料印出。





  • am


  • array $array1


  • array $array2...




將傳入的所有陣列結合成一個陣列。





  • env


  • string $key




由可用的管道取得環境變數。這個函式是準備在$_SERVER或$_ENV被關閉時使用的。



這函式還會負責在Server不支援時,模擬PHP_SELF和DOCUMENT_ROOT。
事實上,最好都用env()取代$_SERVER或getenv()(特別是如果你想要開放程式給別人用),因為他會自動模擬所有的狀況。





  • cache


  • string $path


  • string $expires


  • string $target = 'cache'




把$data的資料存放在CACHE/$path目錄內作為快取,CACHE預設為/app/tmp/。
$expires裡放的時間字串格式必需是strtotime()能接受的格式。
$target則可以是'cache'或'public'。


譯註:'public'時則暫存在WEB_ROOT/$path/目錄下。



  • clearCache


  • string $search


  • string $path = 'views'


  • string $ext




清除快取目錄內的檔案及子目錄。



若$search是字串,則名稱和他相同的目錄或檔名就會被由快取目錄裡移除。
$search還可以是陣列,將多組字串放在陣列中一次指定,便可一次刪除多個檔案或目錄。
如果$search內容是空的,則/app/tmp/cache/views/ 就會被清空。



$path參數用來指定要刪除的檔案與目錄放在/tmp/cache/裡,那個目錄裡。
預設值是'views',所以預設會去/app/tmp/cache/views/目錄內找檔案刪除。



$ext則用來指定要刪除檔案的副檔名。





  • stripslashes_deep


  • array $array




將陣列內所有元素的斜線('/')去除。



  • countdim


  • array $array




計算$array的維度。看是一維陣列,二維陣列...n維陣列。



  • fileExistsInPath


  • string $file




到include_path所指定的各目錄中找尋$file,如果找到則傳回路徑,找不到則傳回false。





  • convertSlash


  • string $string




把正斜線('/')換成底線('_'),若字串中第一個和最後一個字元是底線,則將它刪除。




第二節


CakePHP核心定義常數



ACL_CLASSNAME:指定目前Cakephp使用中的ACL類別名稱。
這個常數讓使用者用於整合第三方類別。



ACL_FILENAME:ACL_CLASSNAME指定的類別存放的檔名。



譯註:ACL 是Access Control List的縮寫,用於控制存取權限。




AUTO_SESSION:如果設成false,則在發出request時,程式不會自動呼叫session_start()。



CACHE_CHECK:如果設成false,會將整個應用程式中view的快取功能關閉。



CAKE_SECURITY:指定session的安全等級,CAKE_SESSION_TIMEOUT會跟者改變。
此值可以是低:'low',中:'medium',高:'high'。
依不同設定,CAKE_SESSION_TIMEOUT會被乘上一個值:





  1. low: 300





  2. medium: 100





  3. high: 10





CAKE_SESSION_COOKIE:應用程式使用的session cookie名稱。



CAKE_SESSION_SAVE:可以設成'php','file'或'database'。





  1. php:Cake使用PHP預設方式處理session(通常定義在php.ini中)。





  2. file:Session的資料會被存放在/tmp中。





  3. database: 使用Cake的session資料庫管理機制處理(請參考"Cake Session Component"一章)。





CAKE_SESSION_STRING:session管理時使用的亂數字串。



CAKE_SESSION_TABLE:存放session資料的資料表(如果CAKE_SESSION_SAVE被設成'database'時)。
如果預設的資料庫連線有設定資料表名稱前置詞,在此就不要再包含它了。



CAKE_SESSION_TIMEOUT:session過期的時間。這個值會再依CAKE_SECURITY被乘上一個值。



COMPRESS_CSS:如果設成true,CCS風格表將在輸出時被壓縮。
要啟動這個功能,必需讓web伺服器有寫入/var/cache 目錄的權限。
使用時,使用/ccss 風格表(不再是/css),或直接使用Controller::cssTag()。



DEBUG:定義CakePHP應用程式執行時,錯誤訊息回報層級。值由0到3:





  1. 0:產品模式。不輸出位何錯誤訊息和除錯訊息。





  2. 1:開發模式。警告,錯誤與除錯訊息都顯示。





  3. 2:和1一樣,不同的是以SQL指令輸出。





  4. 3:和2一樣,但會把目前物件的內容都下來(通常是controller)。





LOG_ERROR:錯誤常數。用來辨別記錄與除錯訊息。目前PHP支援LOG_DEBUG。



MAX_MD5SIZE: 執行md5()使用的最大資料量(bytes)。



WEBSERVICES: 如果設成true,將啟動Cake內建的webservices功能。




Section 3


CakePHP 路徑常數



APP:應用程式目錄的路徑。



APP_DIR:應用程式目錄的名稱。



APP_PATH:應用程式中app目錄的絕對路徑。



CACHE:快取檔目錄所在路徑。



CAKE:應用程式的cake目錄所在路徑。



COMPONENTS:應用程式的compoents目錄路徑。



CONFIGS:設定檔目錄的路徑。



CONTROLLER_TESTS:controller測試目錄的路徑。



CONTROLLERS:應用程式的controller所在路徑。



CSS:CSS檔目錄的路徑。



ELEMENTS:element目錄的路徑。



HELPER_TESTS:helper測試目錄的路徑。



HELPERS:helper目錄的路徑。



INFLECTIONS:inflactions目錄的路徑(通常在設定目錄裡)。



JS:JavaScript檔存放目錄的路徑。



LAYOUTS:layout存放目錄的路徑。



LIB_TESTS:Cake函式庫測試目錄的路徑。



LIBS:Cake函式庫目錄的路徑。



LOGS:記錄檔存放目錄的路徑。



MODEL_TESTS:model測試目錄的路徑。



MODELS:model目錄的路徑。



SCRIPTS:Cake script目錄的路徑。



TESTS:測試目錄的路徑(model,controller等測試目錄的父目錄)。



TMP:tmp目錄的路徑。



VENDORS:vendors目錄的路徑。



VIEWS:view目錄的路徑。




第四節


CakePHP Webroot 設定路徑



CORE_PATH:Cake核心函式庫路徑。



WWW_ROOT:應用程式的webroot目錄的路徑。



CAKE_CORE_INCLUDE_PATH:Cake核心函式庫路徑。



ROOT:CakePHP最基底的index.php所在的目錄。



WEBROOT_DIR:應用程式的webroot目錄路徑。


CakePHP使用手冊-AJAX Helper

轉貼自 http://www.ezluk.org/

第二節



AJAX Helper



Cake的Ajax helper使用最流行的Prototype和script.aculo.us二大函式庫控制Ajax與客戶端特效。
所以,為了要使用這個helper,你必需從http://script.aculo.us下載最近的版本,放在/app/webroot/js/
另外,想使用Ajax helper的view還必需把這些函式庫包含進去。



這helper裡大部分函式都需要一個特別的陣列參數,$options。
$options用來指定Ajax操作中使用的各種參數。以下說明可以指定的值:




AjaxHelper $options 參數



/* 一般選項 */



$options['url']         // 這個動作要呼叫的URL。



$options['frequency']   // remoteTimer()或observeField()呼叫的間隔秒數。



$options['update']      // 根據Ajax操作結果進行更新的元素的DOM ID。



$options['with']        // 和Ajax表單提交時一併傳送和serialize的表單

                        // 元素的DOM ID。



$options['type']        // 設定值是'asynchronous'(預設)和'synchronous'

                   
    // 其中之一。可選擇操作模式。


/* 回呼函式 : XMLHttpRequest執行過程中,特定時間點所執行的JS 程式碼。*/



$options['loading']     // 流覽器將遠端文件載入時執行的JS 程式碼。



$options['loaded']      // 流覽器將遠端文件載入完成時執行的JS 程式碼。



$options['interactive'] // 當使用者可以和遠端文件互動時執行的程式碼,

                   
    // 即使還沒完全載入。

   

$options['complete']    // XMLHttpRequest完成時執行的JS 程式碼。



$options['confirm']     // XMLHttpRquest動作開始前的確認對話框顯示的文字。



$options['condition']   // XMLHttpRequest初始化前需要符合的JS 條件。



$options['before']      // request初始前呼叫的JS程式碼。



$options['after']       // 在request初始化完成之後,文件載入之前執行的JS程式。



以下是讓Ajax在Cake中既快又容易的幾個helper的函式:





  • link


  • string $title


  • string $href


  • array $options


  • boolean $confirm


  • boolean $escapeTitle




建立一個取回位於$options['url']的連結,標題使用$title,完成時更新設定的DOM元素。
這函式可以使用所有的回呼函式。





  • remoteFunction


  • array $options




這函式產生執行遠端呼叫所需的JavaScript。
主要當成linkToRemote的helper。
除非需要產生一些特別的script,否則很少用到。





  • remoteTimer


  • array $options




定期呼叫$options['url']指定的動作,時間間隔由$options['frequency']定義,單位為秒,預設為10秒。
通常使用於用遠端呼叫的結果更新特定的div(由$options['update']指定)。
這函式可以使用所有回呼函式。





  • form


  • string $action


  • string $type


  • array $options




傳回可以提交至$action的表單標籤,
透過XMLHttpRequest在背景執行可以免除傳統POST需要重新載入的問題。
這樣子傳回的表單資料和一般的方法都一樣(在controller中用$this->params['form']取用)。
接者根據操作結果進行更新$options['update']指定的DOM 元素。
這函式可以使用所有的回呼函式。





  • observeField


  • string $field_id


  • array $options




每$options['frequency']秒檢查一次由$field_id指定的DOM ID代表的欄位,
一旦發現內容有變化,馬上呼叫$options['url']裡的action。
可以更新$options['update']指定的DOM 元素,或由$options['with']指定一個表單元素。
這函式可以使用所有的回呼函式。





  • observeForm


  • string $form_id


  • array $options




和observeField()用途相同,只是它監視的是表單裡所有的元素。





  • autoComplete


  • string $field


  • string $url


  • array $options




產生ID為$field的文字欄文,內具自動完成功能。
$url所指的action應該可以傳回自動完成的字串:
基本上,這action要把一堆由<ul></ul>包起來,未經排序的自動完成字串分開。
如果要讓有自動完成功能的欄位取得blog文章的標題,controller的action看起來會像這樣:



function autocomplete ()

{

    $this->set('posts',

        $this->Post->findAll(

            "subject LIKE '{$this->data['Post']['subject']}'")

        );

    $this->layout = "ajax";

}


然後autocomplete()呼叫的view看起來會像這樣:



<ul>

<?php foreach($posts as $post): ?>

<li><?php echo $post['Post']['subject']; ?></li>

<?php endforeach; ?>

</ul>


實際涵有這種欄位的view,程式碼會像這樣:



<form action="/users/index" method="POST">

    <?php echo $ajax->autoComplete('Post/subject', '/posts/autoComplete')?>

    <?php echo $html->submit('View Post')?>

</form>


autoComplete函式會將這個資訊輸入到文字欄位內,而action所提供的自動完成字串則會被顯示在某些div上。
也可以如下例一般設定這個view的風格:



<style type="text/css">



div.auto_complete {

    position         :absolute;

    width            :250px;

    background-color :white;

    border           :1px solid #888;

    margin           :0px;

    padding          :0px;

}



li.selected { background-color: #ffb; }



</style>




  • drag


  • string $id


  • array $options




讓$id指定的DOM物件可以被拖移。
這函式的$options多了一些額外的參數:



// (版本變號請查script.aculo.us)



$options['handle']     // (v1.0)元素內handle等於設定值的子元素才能被

                   
   // 拖移。這個值必需是元素的參考或id。



$options['handle']     // (V1.5) 功能和上面一樣,除了變成可以設成CCS class。

                   
   // 在元素內的子元素中,第一個屬於這個CCS class的,

                   
   // 會被當成handle。



$options['revert']     // (V1.0) 如果設成true,元素會被拖移結束後回到原位。



$options['revert']     // (V1.5) Revert變成也可以是拖移結束後呼叫的函式參考。



$options['constraint'] // 如果設成'horizontal'或'vertical',拖移的方向會被限

                   
   // 制在水平方向或垂直方向。




  • drop


  • string $id


  • array $options




讓$id所指的DOM元素可以把被可拖移元素放置進去。同樣的,也有一些額外的參數,說明如下:



$options['accept']      // 設定成敍述CCS class的字串或內含字串的Javascript

                   
    // 陣列。只允許屬於這些CCS class的可拖移元素被放置

                   
    // 進去。



$options['containment'] // 可放置的元素只會接受放入在列表中的元素(或元素id)

                   
    // 這個設定值可以是一個元素或多個元素的JavaScript

                        // 陣列.



$options['overlap']     // 如果設成horizontal(水平)或vertical(垂直),則只有在

                   
    // 設定方向上重疊一半以上時才會被放置進去。






  • dropRemote


  • string $id


  • array $options


  • array $ajaxOptions




建立可放置的元素,當有元素被放置在時立即產生XMLHttpRequest。
$options跟drop()的一樣。$ajaxOptions的定義和一般的$options沒二樣。


譯註:找了原始碼後發現,$ajaxOptions會被原封不動的傳入remoteFunction()中,
而remoteFunction的傳入值正是一般常見的$options。


sortable


  • string $id


  • array $options




讓一組浮動的物件(由$id指定DOM元素ID)可排列。
$options 陣列可以把排列方法設定如下:



$options['tag']         // 設定容器內的子元素中屬於這種標籤的才能被排列。

                   
    // 對UL和OL容器來說,值是LI。其他種子元素則必須指定,

                   
    // 預設是LI。



$options['only']        // 進一步限制只擇選屬於這個CCS class的子元素為可排列(如

                   
    // 果設定的是一個內含字串的陣列,則可指定指定多種CCS

                   
    // class)。



$options['overlap']     // 不是vertical(垂直,預設)就是horizontal(水平)。 對

                   
    // 浮動的或水平列表,選horizontal。重直列表選vertical。



$options['constraint']  // 把可拖移元素的移動方向限制在垂直(vertical)或水平

                        // (horizontal)方向上。.



$options['containment'] // 讓可排列的元素間可以拖放。設定值是元素或元素ID的陣列,

                   
    // 當然是指容器內的元素。



$options['handle']      // 用handle屬性建立打拖移元素,handle屬性請看drag()

                        // 的敍述。

 




  • editor


  • string $id


  • string $url


  • array $options




使用DOM id為$id的元素建立嵌入型編輯器。
這種編輯器不在編輯模式時時會變形成一排文字,滑鼠過去時會亮起來,按下去會進入編輯模式,隨即放大成一般編輯元素的編輯器。
第二個參數是當按下確定時,資料被傳送的URL。
嵌入型編輯器更詳細的資料可以在此找到
Script.aculo.us
wiki.




網誌存檔

關於我自己

Aspire freedom , Hope to do Soming make self complete ~