2010年2月28日 星期日

Zend_Auth、Zend_Acl的使用實例(在Action中使用Acl)

數據庫表:

CREATE TABLE `user` (

`uid` SMALLINT( 5 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 20 ) CHARACTER SET gbk COLLATE gbk_chinese_ci NOT NULL ,
`password` CHAR( 32 ) NOT NULL ,
`role` ENUM( 'user', 'staff', 'admin' ) NOT NULL ,
`truename` VARCHAR( 20 ) CHARACTER SET gbk COLLATE gbk_chinese_ci NOT NULL ,
INDEX ( `role` , `truename` ) ,
UNIQUE (

`username`

)

) ENGINE = MYISAM CHARACTER SET gbk COLLATE gbk_chinese_ci COMMENT = '用戶表';

在數據庫中存儲了一個role字段(枚舉類型),以保存用戶角色信息!

add(new Zend_Acl_Resource('Default'));
$acl->add(new Zend_Acl_Resource('News'));
//上面對應我的兩個module,一個Default,一個News
$acl->addRole(new Zend_Acl_Role('guest'));
$acl->addRole(new Zend_Acl_Role('user'), 'guest');
$acl->addRole(new Zend_Acl_Role('staff'), 'user');
$acl->addRole(new Zend_Acl_Role('admin'));

$acl->allow('guest', array('Default', 'News'), 'view');
$acl->allow('user', array('Default', 'News'), array('reply', 'download'));
$acl->allow('staff', array('Default', 'News'), array('delete', 'update'));
$acl->allow('admin');

//驗證權限,如果沒有登錄則以遊客身份登錄
$auth = Zend_Auth::getInstance();
if(!$auth->hasIdentity())
{
$auth->getStorage()->write((object)array('username' => 'Guest',
'role' => 'guest',
'truename' => '遊客'));
}
$router = new Zend_Controller_Router_Rewrite();
//$router->addRoute('root',new Zend_Controller_Router_Route('/',array('module' =>'News', 'controller' => 'Index', 'Action' => 'index'))); 也是給出默認控制器的
$front = Zend_Controller_Front::getInstance()->setControllerDirectory(array(
'default' => './Default/Controllers',
'News' => './News/Controllers'
))
->setRouter($router)
->setParam('Zend_Acl', $acl)
->setParam('Zend_Auth', $auth)
->setBaseUrl('/zf/index.php')
->setParam('noViewRenderer', true)
->setParam('useDefaultControllerAlways',true)
->throwExceptions(true)->returnResponse(false)
->dispatch();
?>

在Action中使用Zend_Acl(Default模塊中的IndexController,訪問他的downloadAction):

name = '張心靈';
$view->title = '測試';
$view->setScriptPath('./Default/Views/Index');
$view->addScriptPath('./Default/Views');
$this->getResponse()->appendBody($view->render('Index.phtml'));
}
public function downloadAction()
{
$acl = $this->getInvokeArg('Zend_Acl');
if(!$acl->isAllowed($this->getInvokeArg('Zend_Auth')->getStorage()->read()->role, 'Default', 'download')) $this->getResponse()->appendBody('訪問不合法');
else $this->getResponse()->appendBody('合法訪問');
}
}

測試地址:http://localhost/zf/index.php/index/download

當然,據稱更好的辦法是在 preDispatch 方法中控制權限

測試代碼如下:

getInvokeArg('Zend_Acl')->isAllowed($this->getInvokeArg('Zend_Auth')->getStorage()->read()->role, ucfirst($this->getRequest()->getModuleName()), $this->getRequest()->getActionName()))
$this->_forward('index', 'user', 'Default');
}
public function indexAction()
{
$view = new Zend_View;
$view->name = '張心靈';
$view->title = '測試';
$view->setScriptPath('./Default/Views/Index');
$view->addScriptPath('./Default/Views');
$this->getResponse()->appendBody($view->render('Index.phtml'));
}
public function downloadAction()
{
$acl = $this->getInvokeArg('Zend_Acl');
if(!$acl->isAllowed($this->getInvokeArg('Zend_Auth')->getStorage()->read()->role, 'Default', 'download')) $this->getResponse()->appendBody('訪問不合法');
else $this->getResponse()->appendBody('合法訪問');
}
}

執行結果還是OK的!不過就是感覺在 preDispatch 中控制權限比較呆板啦!

運行的Perfect!(感謝CCTV、感謝Channal V................)

很簡單的是,您可以將 訪問不合法那句 改為 _froward 等等,讓用戶登錄就行了,看起來Zend Framework使用還是蠻方便的(除了Zend_XmlRpc,那麼大個Bug,居然這麼就了都沒修復)

2010年2月24日 星期三

圖片縮圖的好用物件

裡面封裝有:
1、上傳圖片功能
2、按指定大小(單位PX)生成縮略圖
3、按指定百分比(原圖百分比)生成縮略圖
4、自動水印功能,包括文字水印和圖片水印。
5、外圍封裝了調用接口,一條語句實現圖片從上傳>>生成縮略圖>>打上水印三部曲。
6、自動識別,當圖片少於多少時不生成縮略圖。
7、自動識別,當圖片小於多少時,不打水印。
8、外圍封裝接口,可以直接調用子功能(上傳、縮略圖、水印)

調用方法:
autoimg(表單中NAME名稱,圖片根目錄下的子目錄名,文件最大上傳大小, 縮略圖寬, 縮略圖高);
//完成,後續處理,將圖片資訊存放數據庫
?>


image.inc.php
base_name = $this->base_name ? $this->base_name : './'.time().'_'.random(6);
return $this->base_name;
}
function get_info($old_img){
if (is_file($old_img)){
$this->img_info = GetImageSize($old_img);
if ($this->img_info['2'] == 2){
$this->func['create'] = 'imagecreatefromjpeg';
$this->func['copy'] = 'imagejpeg';
$this->img_info['extension'] = 'jpg';
}elseif ($this->img_info['2'] == 1){
$this->func['create'] = 'imagecreatefromgif';
$this->func['copy'] = 'imagegif';
$this->img_info['extension'] = 'gif';
}elseif ($this->img_info['2'] == 3){
$this->func['create'] = 'imagecreatefrompng';
$this->func['copy'] = 'imagepng';
$this->img_info['extension'] = 'png';
}else{
$this->error('not image file');
}
}else{
$this->error('file no find');
}

}
function thumb_per($img_url, $img_dir='./together/0/', $in_percent=0.35,$obj_filename=''){
$in_percent = ($in_percent>1 || $in_percent<=0) ? 0.35 : $in_percent ; $this->get_info($img_url);
if ($in_percent != 0){
$this->new_width = ceil($this->img_info['0'] * $in_percent);
$this->new_height = ceil($this->img_info['1'] * $in_percent);
}else{
$this->new_width = ceil($this->img_info['0']);
$this->new_height = ceil($this->img_info['1']);
}
if ($obj_filename!=''){
$this->new_thumb_name = $obj_filename;
}
$this->create_sub($img_url,$img_dir);
return $this->file_dir.$this->base_name.'.'.$this->img_info['extension'];
}
function thumb_abs($img_url, $img_dir='./together/0/', $new_width=120, $new_height=120,$obj_filename=''){
$this->get_info($img_url);
$this->new_width = ceil(abs($new_width))>1 ? ceil(abs($new_width)) : $this->new_width ;
$this->new_height = ceil(abs($new_height))>1 ? ceil(abs($new_height)) : $this->new_height;
if (($this->new_width > $this->img_info['0']) && ($this->new_height > $this->img_info['1'])){
$this->new_width = $this->img_info['0'];
$this->new_height = $this->img_info['1'];
}else{
if ($this->new_width && ($this->img_info['0'] < $this->img_info['1'])) {
$this->new_width = ($this->new_height / $this->img_info['1']) * $this->img_info['0'];
} else {
$this->new_height = ($this->new_width / $this->img_info['0']) * $this->img_info['1'];
}
}
if ($obj_filename!=''){
$this->new_thumb_name = $obj_filename;
}
$this->create_sub($img_url,$img_dir);
return $this->file_dir.$this->base_name.'.'.$this->img_info['extension'];
}
//子創建
function create_sub($img_url,$img_dir){
$image_o = $this->func['create']($img_url);
if(function_exists("imagecopyresampled")){
$image_n = imagecreatetruecolor($this->new_width, $this->new_height);
imagecopyresampled($image_n, $image_o, 0, 0, 0, 0, $this->new_width, $this->new_height, $this->img_info['0'], $this->img_info['1']) ;
}else{
$image_n = imagecreate($this->new_width, $this->new_height);
imagecopyresized($image_n, $image_o, 0, 0, 0, 0, $this->new_width, $this->new_height, $this->img_info['0'], $this->img_info['1']) ;
}
$this->file_dir = $this->file_dir ? $this->file_dir : $img_dir;
$this->new_thumb_name = (!empty($this->new_thumb_name)) ? $this->new_thumb_name : $this->get_name().'_s.'.$this->img_info['extension'] ;
$this->func['copy']($image_n,$this->file_dir.$this->new_thumb_name);
imagedestroy($image_n);
return true;
}
function upload($attach_value,$attach_dir='',$attach_size='1024000'){
global $_FILES;
if(COUNT($_FILES)==0){
$this->error('no files');
}
$this->file_error = $_FILES[$attach_value]['error'];
if ($this->file_error != 0){
$this->error('upload error');
}
$this->file_name = $_FILES[$attach_value]['name'];
$this->file_type = $_FILES[$attach_value]['type'];
$this->file_size = $_FILES[$attach_value]['size'];
$this->file_tmpname = $_FILES[$attach_value]['tmp_name'];
$this->get_info($this->file_tmpname);

if($attach_size && $this->file_size > $attach_size) {
$this->error('max size:'.$this->file_size);
}
if(!is_dir(MK_IMGROOT.$attach_dir)) {
mkdir(MK_IMGROOT.$attach_dir, 0777);
}
$this->file_dir = MK_IMGROOT.$attach_dir;
$this->file_newname = $attach_dir.'/'.$this->get_name().'.'.$this->img_info['extension'];
$this->file_thumbname = $attach_dir.'/'.$this->get_name().'_s.'.$this->img_info['extension'];
$this->file_dirname = MK_IMGROOT.$this->file_newname;

if(function_exists('move_uploaded_file')) {
if(@move_uploaded_file($this->file_tmpname, $this->file_dirname)) {
$attach_saved = true;
}
} elseif(@copy($this->file_tmpname, $this->file_dirname)) {
$attach_saved = true;
}
$return_data = '';
if ($attach_saved){
$return_data = array('name'=>$this->file_newname , 'size'=>$this->file_size , 'type'=>$this->file_type, 'ext'=>$this->img_info[' extension'], 'imgdir'=>$this->file_dirname, 'thumb'=>$this->file_thumbname, 'width'=>$this->img_info['0'], 'height'=>$this- >img_info['1']);

}
return $return_data;
}
function watermark_img($img_url){
if (is_readable(MK_IMGROOT.'./watermark.png')){
$watermark_file = MK_IMGROOT.'./watermark.png';
$image_w = imagecreatefrompng($watermark_file);
}else{
$watermark_file = MK_IMGROOT.'./watermark.gif';
$image_w = imagecreatefromgif($watermark_file);
}
$this->get_info($watermark_file);
$watermark_width = $this->img_info['0'];
$watermark_height = $this->img_info['1'];
$this->get_info($img_url);
if ($this->img_info['2'] <= 3){ $image_o = $this->func['create']($img_url);
if (function_exists("imagecreatetruecolor")){
$image_n = imagecreatetruecolor($this->img_info['0'], $this->img_info['1']);
}else{
$image_n = imagecreate($this->img_info['0'], $this->img_info['1']);
}
imageCopy($image_n, $image_o, 0, 0, 0, 0, $this->img_info['0'], $this->img_info['1']);
unset($watermark_file);
$watermark_x = $this->img_info['0'] - $watermark_width;
$watermark_y = $this->img_info['1'] - $watermark_height;
imageCopy($image_n, $image_w, $watermark_x, $watermark_y, 0, 0, $watermark_width, $watermark_height);

$this->func['copy']($image_n,$img_url);
imagedestroy($image_n);
}else{
return false;
}
}
function watermark_text($img_url,$text_message='www.7ego.cn'){
$this->get_info($img_url);
if ($this->img_info['2'] <= 3){ $image_o = $this->func['create']($img_url);
if (function_exists("imagecreatetruecolor")){
$image_n = imagecreatetruecolor($this->img_info['0'], $this->img_info['1']);
}else{
$image_n = imagecreate($this->img_info['0'], $this->img_info['1']);
}
imageCopy($image_n, $image_o, 0, 0, 0, 0, $this->img_info['0'], $this->img_info['1']);
$text_font = MK_ROOT.'en.fon';
$text_color = imagecolorallocate($image_n, 0, 0, 0);
$text_bgcolor = imagecolorallocate($image_n, 150, 150, 150);
$bg_color = imagecolorallocate($image_n, 250, 250, 200);
$text_width = imagefontwidth($text_message)*(strlen($text_message)-1)*2;
$text_height = imagefontheight($text_message)*2;
imagefilledrectangle($image_n, 2, 0, $text_width, $text_height, $bg_color);
@imagettftext($image_n, 2, 0, 11, 11, $text_bgcolor, $text_font, $text_message);
imagettftext($image_n, 2, 0, 10, 10, $text_color, $text_font, $text_message);
$this->func['copy']($image_n,$img_url);
imagedestroy($image_n);
}
}
function autoimg($attach_value,$attach_dir='',$attach_size='1024000', $new_width=120, $new_height=120){
$imgreturn = $this->upload($attach_value,$attach_dir,$attach_size);
//if ($imgreturn['width']>800){
// $this->thumb_abs($imgreturn['imgdir'], $this->file_dir, 640, 480,$imgreturn['imgdir']);
//}
$this->thumb_abs($imgreturn['imgdir'], $this->file_dir, $new_width, $new_height);
if ($imgreturn['width']>160 OR $imgreturn['height']>160){
$this->watermark_img($imgreturn['imgdir']);
$this->watermark_text($imgreturn['imgdir'],'www.7ego.cn');
}
return $imgreturn;
}
function error($msg){
global $_MK;
showmessage($msg,$_MK['reff']);
function_exists('mexit') ? mexit() : exit();
}
}
?>

PHP生成靜態網頁

最近研究PHP的一些開發技術,發現PHP有很多ASP所沒有的優秀功能,可以完成一些以前無法完成的功能,例如動態生成HTML靜態頁面,以減少服務器CPU的負載,提高用戶訪問的速度。

我們知道,PHP讀取MYSQL動態顯示,在訪問量大的情況下,會有很多性能問題,如果租用別人的虛擬主機,則會因為CPU消耗過多而被限制CPU,導致網頁無法訪問。我這裡給出一個PHP動態生成HTML的方法,可以極大降低服務器CPU負荷。

首先設置.htaccess文件,將動態調用的參數轉換為靜態的HTML的URL地址,例如將在post目錄下的文件,轉發到根目錄的wp- post.php文件中,加入的語句類似:RewriteRule ^post /([a-z0-9\-]+\.html)$ wp- post.php?$1$2

然後修改wp-post.php文件,在文件的開頭加入以下PHP代碼:
ob_start();
$qstring = isset($_SERVER["QUERY_STRING"]) ? $_SERVER["QUERY_STRING"] : "";
define("HTML_FILE", $_SERVER['DOCUMENT_ROOT']."/post/".$qstring);
if (file_exists(HTML_FILE))
{
$lcft = filemtime(HTML_FILE);
if (($lcft + 3600) > time()) //判斷上次生成HTML文件是否超過1小時,若沒有才直接輸出文件內容
{
echo(file_get_contents(HTML_FILE));
exit(0);
}
}


之後是現有的PHP的代碼,然後在當前代碼的最後面加上如下的PHP代碼:
define("HTMLMETA","");
$buffer = ob_get_flush();
$fp = fopen(HTML_FILE, "w");
if ($fp)
{
fwrite($fp, $buffer.HTMLMETA);
fclose($fp);
}


好了,然後查看你的靜態HTML頁面,如果頁面尾部出現了註釋行,說明已經成功的創建了靜態HTML文件。

這個方法的一個應用就是我先前寫的那個“WordPress年度博客統計插件”,這個統計插件由於查詢十多次數據庫,很多人訪問的時候會有很大性能問題,使用我介紹的這種動態生成HTML技術後,一天就查詢一次,生成一次統計排行,完美解決了查詢數據庫的性能問題。

MySQL的隨機數、MySQ隨機選取數據、MySQ隨機查詢數據、MySQ隨機更新數據

本文實現了MySQL的隨機數、MySQ隨機選取數據、MySQ隨機查詢數據、MySQ隨機更新數據。

MySQ隨機查詢數據

以前在群裡討論過這個問題,比較的有意思。 mysql的語法真好玩。他們原來都想用PHP的實現隨機,但取出多條好像要進行兩次以上查詢。翻了手冊,找到了下面這個語句,可以完成任務了:
SELECT * FROM table_name ORDER BY rand() LIMIT 5;


MySQL的rand()函數在手冊裡是這麼說的:
RAND()
RAND(N)
返回在範圍0到1.0內的隨機浮點值。如果一個整數參數N被指定,它被用作種子值。


關於MySQL的rand()函數的效率問題,大家可以參考《MySQL Order By Rand()效率》:http://www.phpq.net/mysql/mysql-order-by-rand.html。

實際效果:
> select RAND();
-> 0.5925
mysql> select RAND(20);
-> 0.1811
mysql> select RAND(20);
-> 0.1811
mysql> select RAND();
-> 0.2079
mysql> select RAND();
-> 0.7888


MySQ隨機更新數據

如何寫一個語句能一下更新幾百條MYSQL數據?

需要測試的MYSQL數據庫裡面有一個上萬條數據的數據庫,如何寫一個PHP文件一下每次更新幾百條信息?我都是寫一個循環一次更新一條信息,這樣我知道用WHILE寫就可以了,要是一次更新好比100條數據改如何寫呢?

正確答案:
UPDATE cdb_posts SET views = rand();


其實在insert命令中,value()裡面用rand(),注意字段寬度是否夠,一直以為mysql隨機查詢幾條數據,就用下面的語句就可以了:
SELECT * FROM `table` ORDER BY RAND() LIMIT 5

2010年2月19日 星期五

Ubuntu中安裝LAMP

安裝Apache2

sudo apt-get install apache2

安裝MySQL
sudo apt-get install mysql-server libmysqlclient15-dev

安裝PHP
sudo apt-get install php5 php5-common libapache2-mod-php5 php5-gd php5-dev curl libcurl3 libcurl3-dev php5-curl

安裝phpmyadmin
sudo aptitude install phpmyadmin

安裝SSL
sudo apache2-ssl-certificate

sudo a2enmod ssl

echo "Listen 443" | sudo tee -a /etc/apache2/ports.conf

sudo ln -s /etc/apache2/sites-available/ssl /etc/apache2/sites-enabled/ssl


sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/ssl

sudo gedit /etc/apache2/sites-available/ssl


設定443port的網站

NameVirtualHost *:443


ServerAdmin webmaster@localhost

SSLEngine On
SSLCertificateFile /etc/apache2/ssl/apache.pem

DocumentRoot /var/www/

Options FollowSymLinks
AllowOverride None



Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
# This directive allows us to have apache2's default start page
# in /apache2-default/, but still have / go to the right place
# Commented out for Ubuntu
#RedirectMatch ^/$ /apache2-default/


ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

AllowOverride None
Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all


ErrorLog /var/log/apache2/error.log

# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn

CustomLog /var/log/apache2/access.log combined
ServerSignature On

Alias /doc/ "/usr/share/doc/"

Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128




安裝apache的模組

sudo a2enmod rewrite


設定Apche轉送

sudo gedit /etc/apache2/sites-available/default


AllowOverride All

重啟Apache2

sudo apache2 -k restart


PS要安裝php-pear要先有phpize 所以要先安裝php5-dev

sudo apt-get install php5-dev

sudo apt-get install php-pear

sudo pecl install pdo

sudo pecl install pdo_mysql

如果有錯誤必須先安裝
ERROR: `/tmp/tmpRiQ5ax/PDO_MYSQL-1.0.2/configure' failed

先裝好mysql的lib,再試著安裝pdo_mysql
sudo apt-get install libmysqlclient15-dev


接下來修改php.ini檔

sudo gedit /etc/php5/apache2/php.ini

sudo vim /etc/php5/apache2/php.ini

2010年2月11日 星期四

用PHP來做Cluster的FILE

http://code.google.com/p/finefs/

2010年2月4日 星期四

ZendFrameWork 下載檔案

關閉layout

$this->blankPage();
header("Content-type: application/vnd.ms-excel");
header("Content-disposition: csv" . date("Y-m-d") . ".csv");
header("Content-disposition: filename=" . $filename . ".csv");
print $contactsHeader . "\r\n" . $csv_output;exit;

ZendFramework 代碼片段

config.ini 文件
[general]
db.adapter = PDO_MYSQL
db.config.host = localhost
db.config.username = root
db.config.password =
db.config.dbname = zftest

$config=new Zend_Config_Ini('./config/config.ini','general');
//zend_config_ini加載配置文件用
$db=Zend_Db::factory($config->db->adapter,
$config->db->config->toArray());
Zend_Db::factory("資料庫的類型","把config文件中的内容换成陣列")

防止資料庫攻擊方法:
1、$value=$db->quote('ADFA'DF');
quote自動為單引號行過濾加上雙引号
2、quoteInto()
$value=$db->quoteInto();
多筆查詢


$db->quoteInto('(a =? AND ', $a) .
$db->quoteInfo('b = >)', $b) . 
$db->quoteInfo(' OR ( c != ?)', $c)

3、直接查询
$sql=$db->quoteInto('select * from example where date>?','2006-01-01');
$result=$db->query($sql);
$rows=$result->fetchAll();
4、或者使用占位符号:placeholder 如:
$result=$db->query('select * from exaple where date>:placeholder',
array('placeholder'=>'2006-01-01')
$rows=$result->fetchAll();
5、prepare()方法绑定
$stmt=$db->prepare('select * from example where date>:placeholder');
$stmt->bindvalue('placeholder','2006-01-01');
$stmt->execute();
$rows=$stmt->fetchAll();
6、交易處理
$db->beginTransaction();
try{
$db->query(...);
$db->commit();
}catch(Exception $e){
$db->rollback();
echo $d->getMessage();
}
7、插入數據行
$row=array('title'=>'king','name'=>'baobao',color=>'blue');
$table='uer_table';
$rows_affected=$db->insert($table,$row);
$last_insert_id=$db->lastInsertId();
8、更新數據行
$set=array('name'=>'lailai')
$table='user_table'//更新的数据表
//where語法
$where=$db->quotuinto('name=?','baobao');
//更新資料表,回傳行數
$rows_affected=$db->update($table,$set,$where);
9、刪除資料航
$table='user_table'
where 語句
$where =$db->quoteinto('first_name=?','patsy');
//删除資料並得到影響的行數
$rows_affected=$db->delete($table,$where);
10、取回查詢結果
fetchAll();fetchAssoc();fetchCol();fetchOne();fetchPairs();fetchRow();
//fetchAll取回所有結果集合,並作為連續的雜湊返回
$result=$db->fetchAll(
'select * from round_table where noble_title=:title',
array('title'=>'sir')
);
fetchAssoc()//作为关联数组返回
fetchcol()//取回结果行的第一个字段名
fetchOne()//取回第一个字段值
fetchPairs()//取回一个相关数组,第一个字段为码,第二个字段为值
fetchRow()//取得结果集中的第一行
$config = new Zend_Config_Ini(APP_DIR . '/config/config.ini', 'general');

$this->getHelper('layout')->disableLayout();
$this->getHelper('viewRenderer')->setNoRender();

headScript()->captureStart(); ?>
headScript()->captureEnd(); ?>


$this->view->getHelper('userMemUrl')->userMemUrl('info')

// 分頁頁碼
$this->per = 10;
$len = $this->db->fetchOne("select count(*) from `feedback` where `active`=1 and `memorial_id`=$this->mid");
$pager = new Pager($len, $this->per);
$pager->setAlign('right');
$this->view->pager = $pager->getNavigation();
$start = ($pager->getCurrentPage()-1)*$this->per;
$obj = new Feedback();
$this->view->list = $obj->fetchAll("`active`=1", 'poscode desc', $this->per, $start);


/* 读取上一张,下一张 */
$this->view->prevRow = $obj->fetchRow("`active`=1 and `id`='$row->id' and `poscode`>'$row->poscode'", 'poscode asc', 1, 0);
$this->view->nextRow = $obj->fetchRow("`active`=1 and `id`='$row->id' and `poscode`<'$row->poscode'", 'poscode desc', 1, 0);

上一条:
prevRow): ?>
prevRow->title; ?>


这是第一条


下一条:
nextRow): ?>
nextRow->title; ?>

这是最后一条



$this->view->headLink()->appendStylesheet($this->baseDir . '/css/gardens.css');

$this->view->headScript()->appendFile($this->baseDir . '/js/jquery.js');
$this->view->headScript()->appendFile($this->baseDir . '/js/common.js');


if(!$this->_request->isPost()) {
$this->view->useIframe = true;
} else {
$data = $this->_request->getPost();
if(!$data['content']) {
echo Func::feedtop('alert("生平簡介不能為空,請重新輸入!");');
exit();
}
$row->content = $data['content'];
$rs = $row->save();
if($rs) {
echo Func::feedtop('alert("生平簡介更新成功!");');
exit();
} else {
echo Func::feedtop('alert("生平簡介更新失敗,請稍後重試!");');
exit();
}
}

// ajax 響應
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('select-wish', 'html')
->addActionContext('send-wish', 'html')
->initContext();


$this->_flashMessenger = $this->_helper->getHelper('FlashMessenger');

$this->_flashMessenger->addMessage('修改成功!');
$this->view->messages = $this->_flashMessenger->getMessages();


echo Func::feedtop('winFunc.go("' .$this->view->getHelper('baseUrl')->baseUrl() . '/user/pay/cart/id/' .$rs. '");');



// 刷新 SESSION
$auth = $this->getInvokeArg('auth');
$auth->getStorage()->write($row);


//驗證碼
$this->vcode = new Zend_Session_Namespace('vcode');
if ($data['vcode'] != $this->vcode->user_login) {
echo Func::feedtop('alert("驗證碼輸入有誤,請確認!");$("#vcode")[0].focus()');
exit();
}

Zend Framework添加CSS 和 JS的方法

$this->view->headLink()->appendStylesheet('/c/css/homepage.css');
$this->view->headLink()->appendStylesheet($baseUrl.'/css/admin/tinybrowser.css');
$this->view->jQuery()->addJavascriptFile($baseUrl . '/js/admin/tiny_functions.js');

Zend Framework轉向

Zend Framework

Zend, PHP
一. render
不指定render
结果: {当前Module}/{当前Controller}/{当前Action}.phtml

$this->render('bar') ;
结果: {当前Module}/{当前Controller}/bar.phtml

二. forward
$this->_forward('bar') ;
结果: {当前Module}/{当前Controller}/bar

$this->_forward('bar', 'foo') ;
结果: {当前Module}/foo/bar

$this->_forward('bar', 'foo', 'hoge') ;
结果: hoge/foo/bar

$params = array(
'a' => '1',
'b' => '2'
) ;
$this->_forward('bar', 'foo', 'hoge', $params) ;
结果: /hoge/foo/bar/a/1/b/2

三. redirect
$this->_redirect('/hoge') ;
结果: /hoge

$this->_redirect('/hoge/foo') ;
结果: /hoge/foo

$this->_redirect('/hoge/foo/bar') ;
结果: /hoge/foo/bar

$this->_redirect('http://localhost/hoge/foo/bar') ;
结果: http://localhost/hoge/foo/bar

$this->_redirect('http://localhost/hoge/foo/bar?a=1&b=2') ;
结果: http://localhost/hoge/foo/bar?a=1&b=2

四. 特殊情况
不使用 layout
结果: $this->_helper->layout()->disableLayout() ;

不使用 view
结果: $this->_helper->viewRenderer->setNoRender() ;