本人原本是用編輯器以OOP來寫PHP, 但因為有大大說別再刻輪子了, 所以下定決心要好好學個MVC架構的框架, 讓自己的程式結構分明、易維護. 最後經過多方比較後決定學Yii framework, 學習的過程中, 深刻感受到國內關於這個框架的資源, 相較國外及大陸之下明顯不足, 所以希望自己能為台灣的開發者盡一份力. 我是Joker 一位自學者, 一起來大玩特玩吧!
2014年12月25日 星期四
yii redirect轉址說明
跳到絕對路徑:
$this->redirect('http://code-joker.blogspot.tw/');
跳到本身Controller的某個action:
$this->redirect(array('index');
在module(模組)裡要跳到預設的Controller裡(protected/controllers/):
$this->redirect(array('/user/index');
在module(模組)裡要跳到本身模組的其他Controller:
$this->redirect(array('other/index');
在module(模組)裡要跳到其他模組的其他Controller:
$this->redirect(array('/ortherModule/otherController/index');
PS:常用到的URL請取得方式參考下面連結
參考:
YII路由跳转forward\redirect
Yii的常用URL和渲染方法
2014年10月31日 星期五
yii 產生pdf 大破解 (史上最清楚的TCPDF教學)
前言
要在yii使用tcpdf根本不用去找別人寫的套件, 只要載入官方的檔案就可以了!
ps: 我會將tcpdf檔案放在extensions純粹是讓整個架構合理, 日後管理起來比較好找而已.
前置作業
2. 解壓縮後將examples資料夾刪掉 (不需要), 這時候全部的檔案會在一個tcpdf的資料夾裡
3. 將tcpdf資料夾傳到yii 的第三方套件資料夾 (protected/extensions)
4. 到yii 的設定檔 (protected/config/main.php), 將tcpdf路徑加進去
'import' => array(
'application.models.*',
'application.components.*',
'ext.tcpdf.*',
),
5. 進到tcpdf的設定檔 (extensions/tcpdf/config/tcpdf_config.php) *重要
-如果你產生的pdf裡面要有logo的話, 先取消掉 K_PATH_IMAGES的註解, 然後設定你的logo路徑:
define ('K_PATH_IMAGES', '你的logo路徑');
如果我們的路徑是在專案下的img資料夾, 那路徑就是 var/www/ProjectName/img/member/
但是, 更活一點的寫法可以這樣:
$imgPath = dirname(Yii::app()->BasePath) . '/img/member/';
define ('K_PATH_IMAGES', $imgPath);
-設定可以顯示中文字
將PDF_FONT_NAME_MAIN的helvetica改成msungstdlight
開發
Contrller
1. 在你的controller裡設定空白的layout, 設定的方式參考下面兩篇
所謂空白layout就是裡面只有這行:
<?php echo $content; ?>
ps: 要用空白layout的原因是, 在tcpdf產生出pdf前, 如果有任何輸出的話就會出錯!
2.
public function actionPrint()
{
$this->layout = '//layouts/nothing';
$data = array(
'name' => '中二不解釋',
'age' => '18',
'tel' => '0910855555',
'note' => '沒事就打lol',
);
$html = Yii::app()->controller->renderPartial('print_templet', array('data'=>$data), true, true);
$this->render('print',array(
'html'=>$html,
));
}
View
1. print_templet.php
<table>
<tr>
<td>
姓名
</td>
<td>
<?php echo data['name']; ?>
</td>
</tr>
<tr>
<td>
年紀
</td>
<td>
<?php echo data['age']; ?>
</td>
</tr>
<tr>
<td>
電話
</td>
<td>
<?php echo data['tel']; ?>
</td>
</tr>
<tr>
<td>
備註
</td>
<td>
<?php echo data['note']; ?>
</td>
</tr>
</table>
2. print.php
$pdf = new tcpdf('P', 'mm', 'A4', true, 'UTF-8', false);
$pdf->SetCreator('Joker love you');
$pdf->SetAuthor('joker');
$pdf->SetTitle('Welcome to joker.tw!');
$pdf->SetSubject('TCPDF Tutorial');
$pdf->SetKeywords('TCPDF, PDF, PHP');
$pdf->setHeaderData('logo.png', 30, 'joker.tw', '反攻大陸就靠promo!', array(0,64,255), array(0,64,128));
$pdf->setFooterData(array(0,64,0), array(0,64,128));
$pdf->setHeaderFont(Array('msungstdlight', '', '10'));
$pdf->setFooterFont(Array('helvetica', '', '8'));
$pdf->SetDefaultMonospacedFont('courier');
$pdf->SetMargins(15, 27, 15);
$pdf->SetHeaderMargin(5);
$pdf->SetFooterMargin(10);
$pdf->SetAutoPageBreak(TRUE, 25);
$pdf->setImageScale(1.25);
$pdf->setFontSubsetting(true);
$pdf->SetFont('msungstdlight', '', 14, '', true);
$pdf->AddPage();
$pdf->writeHTML($html, true, false, true, true, '');
$style = array(
'border' => 2,
'vpadding' => 'auto',
'hpadding' => 'auto',
'fgcolor' => array(0,0,0),
'bgcolor' => false, //array(255,255,255)
'module_width' => 1, // width of a single module in points
'module_height' => 1 // height of a single module in points
);
$pdf->write2DBarcode('www.google.com.tw', 'QRCODE,H', 20, 210, 40, 40, $style, 'N');
$pdf->Text(20, 200, '掃我者得永生');
$pdf->Output('penisIsGood.pdf', 'I');
技術說明
1. renderPartial這個很屌, 它跟render的差異在於:
-renderPartial本質上就是include一個php文件。它和render的不同點在於後者在include完一個php文件後還會把顯示的內容安插到一個layout中。
以上說明引用自 renderPartial 的用法
-renderPartial的參數可以看官方說明
-參數的說明可以看 Yii的中渲染和的RenderPartial的區別
標籤:
import class,
renderPartial,
tcpdf,
yii
2014年10月16日 星期四
yii 如何在一個controller使用不同的layout?
關於yii的layout結構我們可以先參考這篇 yii 設定你的layout
如果我們的controller裡有兩個action, 我要如何各別設定layout?
class IntroductionController extends Controller {
public $layout = '//layouts/common'; //設一個這個controller預設的layout
public function actionShowMe() {
$this->render('showme'); //使用上面預設的layout!
}
public function actionSeeYou(){
$this->layout = '//layouts/custom_layout'; //這樣就可以使用別的layout了!
$this->render('seeyou');
}
}
參考資料:
2014年10月11日 星期六
yii 設定你的layout
我們先了解一下yii的layout運作流程
1. 我們建的Controller都會在一開始繼承一個叫Controller的Class
class IndexController extends Controller
{
....
}
2. 這個Controller的Class在哪裡呢? 原來就在components (組件)裡, 路徑如下:
components/Controller.php
裡面結構很簡單
class Controller extends CController
{
public $layout='//layouts/column1'; //這是yii預設的layout
public $menu=array();
public $breadcrumbs=array();
}
3. //layouts/column1在哪裡呢? 在views/layouts/column1.php
結構如下:
<?php $this->beginContent('//layouts/main'); ?>
<div id="content">
<?php echo $content; ?>
</div><!-- content -->
<?php $this->endContent(); ?>
4. 同理//layouts/main的路徑就在views/layouts/main.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="language" content="en" />
<!-- blueprint CSS framework -->
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/screen.css" media="screen, projection" />
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/print.css" media="print" />
<!--[if lt IE 8]>
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/ie.css" media="screen, projection" />
<![endif]-->
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/main.css" />
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/form.css" />
<title><?php echo CHtml::encode($this->pageTitle); ?></title>
</head>
<body>
<div class="container" id="page">
<div id="header">
<div id="logo"><?php echo CHtml::encode(Yii::app()->name); ?></div>
</div><!-- header -->
<div id="mainmenu">
<?php $this->widget('zii.widgets.CMenu',array(
'items'=>array(
array('label'=>'Home', 'url'=>array('/site/index')),
array('label'=>'About', 'url'=>array('/site/page', 'view'=>'about')),
array('label'=>'Contact', 'url'=>array('/site/contact')),
array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest),
array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest)
),
)); ?>
</div><!-- mainmenu -->
<?php if(isset($this->breadcrumbs)):?>
<?php $this->widget('zii.widgets.CBreadcrumbs', array(
'links'=>$this->breadcrumbs,
)); ?><!-- breadcrumbs -->
<?php endif?>
<?php echo $content; ?>
<div class="clear"></div>
<div id="footer">
Copyright © <?php echo date('Y'); ?> by My Company.<br/>
All Rights Reserved.<br/>
<?php echo Yii::powered(); ?>
</div><!-- footer -->
</div><!-- page -->
</body>
</html>
好, 重點來了! $content就是你render指定的view內容
所以有感覺了嗎?
也就是除了$content以外的hmtl在畫面上就是固定的!!
這樣我們就可以任意調整我們的布局了! (ex: 左側選單固定、上方選單固定...etc)
那我們該如何使用自己寫的layout呢? 很簡單!
1. 把你的layout丟到layouts資料夾裡
2. 進到你的controller (不管是在controllers還是modules都可以), 加入下面的code
public $layout='//layouts/你的layout檔名';
ps: 檔名就好, 不用加副檔名
3. 結束!
那如果是module的話呢?
1. 把你的layout丟到你module的view裡 (ex: modules/user/view/layouts/)
2. 進到你module的controller, 加入這句
public $layout='//modules/user/view/layouts/你的layout檔名';
3. 大功告成!
1. 我們建的Controller都會在一開始繼承一個叫Controller的Class
class IndexController extends Controller
{
....
}
2. 這個Controller的Class在哪裡呢? 原來就在components (組件)裡, 路徑如下:
components/Controller.php
裡面結構很簡單
class Controller extends CController
{
public $layout='//layouts/column1'; //這是yii預設的layout
public $menu=array();
public $breadcrumbs=array();
}
3. //layouts/column1在哪裡呢? 在views/layouts/column1.php
結構如下:
<?php $this->beginContent('//layouts/main'); ?>
<div id="content">
<?php echo $content; ?>
</div><!-- content -->
<?php $this->endContent(); ?>
4. 同理//layouts/main的路徑就在views/layouts/main.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="language" content="en" />
<!-- blueprint CSS framework -->
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/screen.css" media="screen, projection" />
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/print.css" media="print" />
<!--[if lt IE 8]>
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/ie.css" media="screen, projection" />
<![endif]-->
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/main.css" />
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/form.css" />
<title><?php echo CHtml::encode($this->pageTitle); ?></title>
</head>
<body>
<div class="container" id="page">
<div id="header">
<div id="logo"><?php echo CHtml::encode(Yii::app()->name); ?></div>
</div><!-- header -->
<div id="mainmenu">
<?php $this->widget('zii.widgets.CMenu',array(
'items'=>array(
array('label'=>'Home', 'url'=>array('/site/index')),
array('label'=>'About', 'url'=>array('/site/page', 'view'=>'about')),
array('label'=>'Contact', 'url'=>array('/site/contact')),
array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest),
array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest)
),
)); ?>
</div><!-- mainmenu -->
<?php if(isset($this->breadcrumbs)):?>
<?php $this->widget('zii.widgets.CBreadcrumbs', array(
'links'=>$this->breadcrumbs,
)); ?><!-- breadcrumbs -->
<?php endif?>
<?php echo $content; ?>
<div class="clear"></div>
<div id="footer">
Copyright © <?php echo date('Y'); ?> by My Company.<br/>
All Rights Reserved.<br/>
<?php echo Yii::powered(); ?>
</div><!-- footer -->
</div><!-- page -->
</body>
</html>
好, 重點來了! $content就是你render指定的view內容
所以有感覺了嗎?
也就是除了$content以外的hmtl在畫面上就是固定的!!
這樣我們就可以任意調整我們的布局了! (ex: 左側選單固定、上方選單固定...etc)
那我們該如何使用自己寫的layout呢? 很簡單!
1. 把你的layout丟到layouts資料夾裡
2. 進到你的controller (不管是在controllers還是modules都可以), 加入下面的code
public $layout='//layouts/你的layout檔名';
ps: 檔名就好, 不用加副檔名
3. 結束!
那如果是module的話呢?
1. 把你的layout丟到你module的view裡 (ex: modules/user/view/layouts/)
2. 進到你module的controller, 加入這句
public $layout='//modules/user/view/layouts/你的layout檔名';
3. 大功告成!
標籤:
components,
layout
2014年10月10日 星期五
yii 如何改變登入路徑
1. 打開你的config/main.php
2. 在components的user新增loginUrl
'components'=>array(
'request'=>array(
.....
),
),
'session' => array(
.....
),
),
'user'=>array(
'loginUrl'=>array('admin/index/login'),
'allowAutoLogin'=>true,
),
)
我的路徑是admin/index/login是因為我登入頁的相關路徑如下:
controller -> modules/admin/controllers/indexController.php
view -> modules/admin/views/index/login.php
至於登入的controller怎麼寫? 很簡單
1. 打開controllers/SiteController.php
2. 把actionLogin跟actionLogout複製起來, 貼到你的登入controller就好了!
ps: 當然, yii預設的管理帳密是寫死在php裡的, 記得改成跟資料庫比對就可以了!
2. 在components的user新增loginUrl
'components'=>array(
'request'=>array(
.....
),
),
'session' => array(
.....
),
),
'user'=>array(
'loginUrl'=>array('admin/index/login'),
'allowAutoLogin'=>true,
),
)
我的路徑是admin/index/login是因為我登入頁的相關路徑如下:
controller -> modules/admin/controllers/indexController.php
view -> modules/admin/views/index/login.php
至於登入的controller怎麼寫? 很簡單
1. 打開controllers/SiteController.php
2. 把actionLogin跟actionLogout複製起來, 貼到你的登入controller就好了!
ps: 當然, yii預設的管理帳密是寫死在php裡的, 記得改成跟資料庫比對就可以了!
標籤:
components,
loginUrl
2014年10月6日 星期一
yii 建立module大解密
兩種方式可以建立module
1. Gii
可以看到yii會幫我們建立以下的資料:
1. cart資料夾
-CartModule.php
2. cart/controllers資料夾
-DefaultController.php
3. cart/views資料夾
4. cart/views/default資料夾
-index,php
2. yiic shell (參考這篇)
跟用Gii建立module的差別在, shell會多新增下面幾個資料夾:
1. components
2. messages
3. models
4. views/layouts
整體來看用shell建立的是比較完整, 不過如果你的module不會用到components跟messages的話, 其實用Gii就夠了!
不用擔心models, 因為一樣可以透過Gii來替你的module建立model, 還有CRUD
(可以參考這篇)
3. Set Module
1. 進到config/main.php
2. 將你的模組 (module) 加進去, 假設你的模組叫user:
'modules' => array(
'user',
// uncomment the following to enable the Gii tool
'gii' => array(
'class' => 'system.gii.GiiModule',
'password' => 'you password',
// If removed, Gii defaults to localhost only. Edit carefully to taste.
'ipFilters' => array('127.0.0.1','::1'),
),
1. Gii
可以看到yii會幫我們建立以下的資料:
1. cart資料夾
-CartModule.php
2. cart/controllers資料夾
-DefaultController.php
3. cart/views資料夾
4. cart/views/default資料夾
-index,php
2. yiic shell (參考這篇)
跟用Gii建立module的差別在, shell會多新增下面幾個資料夾:
1. components
2. messages
3. models
4. views/layouts
整體來看用shell建立的是比較完整, 不過如果你的module不會用到components跟messages的話, 其實用Gii就夠了!
不用擔心models, 因為一樣可以透過Gii來替你的module建立model, 還有CRUD
(可以參考這篇)
3. Set Module
1. 進到config/main.php
2. 將你的模組 (module) 加進去, 假設你的模組叫user:
'modules' => array(
'user',
// uncomment the following to enable the Gii tool
'gii' => array(
'class' => 'system.gii.GiiModule',
'password' => 'you password',
// If removed, Gii defaults to localhost only. Edit carefully to taste.
'ipFilters' => array('127.0.0.1','::1'),
),
yiic shell Error: index.php does not exist or is not an entry script file大解密!
今天我要使用yii 的shell指令時 (參考這篇)
在第一行
yiic shell就出錯了!
它說它找不到index.php~
所以就給它我們用webapp建立專案時, 內建的index.php路徑就可以了!
說明一下:
我的專案名稱是www, 跟framework在同一層目錄下
development
| -framework
| -www
yiic.bat 在framework裡
index,php 在www裡
所以下的指令就會是上面這樣
yiic shell ../www./index.php
假掰一點的表示法就是
>yiic shell webapp path/index.php
2014年8月1日 星期五
yii framework - 如何避免跨站請求偽造攻擊(CSRF)?
要開啟CSRF功能, 必須先到config/main.php裡新增以下code:
'submit' => array(
'delete', 'id' => $model->id),
'confirm' => '你確定要刪除' . $model->name . '?'
),
),
請改為
array('label' => 'Delete', 'url' => '#', 'linkOptions' => array(
'submit' => array(
'delete', 'id' => $model->id),
'confirm' => '你確定要刪除' . $model->name . '?'
'csrf' => true,
),
),
這樣問題就解決嘍^^
'request' => array(
'enableCsrfValidation' => true,
),
避免遭受到CSRF攻擊有兩個注意的地方:
1. GET只能用在查資料, 不能用在其他資料庫的操作.
2. POST必須要能產生一個隨機值並且讓server端能辨識, 進而回傳資料到client端.
所以在yii裡面使用表單傳送(POST)的時候, 一定要使用CHtml::form, 或是Widget的CActiveForm.
千萬不要自己寫HTML, 要不然會出現以下的error:
Error 400
The CSRF token could not be verified.
因為用yii內建的來寫form, 它會生成一個隱藏的input, 裡面會有一個隨機的值, 以防止CSRF攻擊!
另外, 你會發現我們使用gii建立的後台, 刪除功能居然不能用了!!! 怎麼會這樣呢?
其實就像上面說的, GET只能用在查資料, 不能用在其他資料庫的操作.
所以我們必須要做些設定, 以刪除功能為例, 原本的code如下:
array('label' => 'Delete', 'url' => '#', 'linkOptions' => array( 'submit' => array(
'delete', 'id' => $model->id),
'confirm' => '你確定要刪除' . $model->name . '?'
),
),
請改為
array('label' => 'Delete', 'url' => '#', 'linkOptions' => array(
'submit' => array(
'delete', 'id' => $model->id),
'confirm' => '你確定要刪除' . $model->name . '?'
'csrf' => true,
),
),
這樣問題就解決嘍^^
2014年7月17日 星期四
yii framework - 如何上傳照片 (多張)? 使用CMultiFileUpload+getInstances
跟 yii framework - 如何上傳照片 (單張)? 使用CUploadedFile 一樣
要實現多張照片上傳功能, 一樣要在model、conrtoller、view三管齊下才能完成,
我會逐一說明 (以M->V->C的順序).
本次實作的目標:
一次將多張照片上傳至指定資料夾, 並將照片的檔名存到資料庫 (用,分隔每個檔名), 以便之後取用.
Model
在你的models裡的rules()新增以下code:
array('dbFieldsOfTheImage', 'file', 'types'=>'jpeg, jpg, png', 'allowEmpty'=>true),
1. 請將這邊的dbFieldsOfTheImage改為你照片上傳的資料表欄位名稱
2. types指的是, 指定的上傳檔案類型 (如果你要讓人上傳的是excel, 那就打上xls, xlsx...etc)
PS:還有許多參數可做設定, 例如檔案大小限制、錯誤訊息, 可參考 (CFileValidator)
重要:
網路上很多範例都會少了allowEmpty這個參數, 就像這篇 Multiple files uploader with CMultiFileUpload.
結果就會非常慘, 就是會發生檔案上傳了, 但是填寫表格的資料一直存不進資料庫. 然後會出現錯誤:XXX cannot be blank, 然後你就會匪夷所思, 明明檔案都上傳了, 檔名也都抓到了, 為什麼就是存不進去.
原來因為我們在model裡設定它是file, 所以它上傳的是檔案, 而不是一個字串 (檔名), 所以我們必須要設allowEmpty這個參數, 告訴model我們允許它是空的, 這樣在save的時候才不會被model的規則給擋住!!!
這部分我卡了好幾天, 真的很重要阿~ 各位.
View
一樣是改_form.php這個檔案 (框架預設), 修改以下的code:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'bnb-form',
'enableClientValidation'=>true,
'htmlOptions' => array('enctype' => 'multipart/form-data'),
)); ?>
<?php
$this->widget('CMultiFileUpload', array(
'model' => $model,
'attribute' => 'bnbImg',
'accept' => 'jpeg|jpg|png',
'duplicate' => '你選過這個照片了喔!',
'denied' => '請選擇jpeg、jpg、png格式的影像!',
'htmlOptions' => array('multiple' => 'multiple'),
'max' => 5,
));
?>
上傳檔案最重要的就是htmlOptions這個參數裡面的設定一定要是'enctype' => 'multipart/form-data'.
至於'enableClientValidation'=>true, 這個非常好用! 它會依你的model的規則設定來生成對應的JavaScript來做Client端的驗證, 超屌. 不過跟上傳檔案沒關係.
1.
attribute會生成HTML input的id跟name. 例如: 我資料表叫Test, 欄位是fuck, 這時候我設定'attribute' => 'fuck', 就會產生以下code:
<input id="Test_fuck" type="file" value="" name="Test[fuck][]" />
2.
accept - 允許的檔案格式
duplicate - 當選到重複的照片時跳出的警告視窗
denied - 當夾帶不是我們規定的檔案格式時, 跳出的警告視窗
'htmlOptions' => array('multiple' => 'multiple') - 可讓你一次選多張
max - 最多可上傳的檔案數量
別懷疑, 做了這些設定, yii就幫你把它生成JavaScript, 讓你爽的死去活來的!!
重要:
有些人會在CActiveForm裡做AJAX, 所以會加上這個 'enableAjaxValidation'=>false,
在表格有檔案上傳的欄位時千萬不要加那個! 因為它會讓你出錯, 以下擷取官方部分內容:
Conrtoller
public function actionCreate()
{
$model = new Bnb;
if(isset($_POST['Bnb']))
{
$model->attributes=$_POST['Bnb'];
/*
$uploadPath Set info:
Linux: /images/bnb/ , Win: \images\bnb\
*/
$uploadPath = DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'bnb' . DIRECTORY_SEPARATOR;
if($allFilesName=$this->uploadMultiFile($model, 'bnbImg', $uploadPath))
$model->bnbImg = implode(",", $allFilesName);
if($model->save())
$this->redirect(array('view', 'id'=>$model->bnbId));
}
$this->render('create',array(
'model'=>$model,
));
}
private function uploadMultiFile($model, $attr, $path)
{
if($fileInfo = CUploadedFile::getInstances($model, $attr))
{
foreach ($fileInfo as $i=>$file)
{
$formatName = $file->name;
$file->saveAs(Yii::getPathOfAlias('webroot') . DIRECTORY_SEPARATOR . $path . $formatName); //webroot: you'r project/protected
$allFilesName[$i] = $formatName;
}
return ($allFilesName);
}
}
1. 用 DIRECTORY_SEPARATOR 是因為路徑在Linux跟windows不一樣的, 所以為了都能正常運做, 就用了比較長的寫法. (參考 DIRECTORY_SEPARATOR的作用)
2. 將上傳的code單獨寫成uploadMultiFile是為了讓整個可讀性更高, 避免程式絮亂, 以方便維護.
Finish~ thx GOD
參考資料:CMultiFileUpload
要實現多張照片上傳功能, 一樣要在model、conrtoller、view三管齊下才能完成,
我會逐一說明 (以M->V->C的順序).
本次實作的目標:
一次將多張照片上傳至指定資料夾, 並將照片的檔名存到資料庫 (用,分隔每個檔名), 以便之後取用.
Model
在你的models裡的rules()新增以下code:
array('dbFieldsOfTheImage', 'file', 'types'=>'jpeg, jpg, png', 'allowEmpty'=>true),
1. 請將這邊的dbFieldsOfTheImage改為你照片上傳的資料表欄位名稱
2. types指的是, 指定的上傳檔案類型 (如果你要讓人上傳的是excel, 那就打上xls, xlsx...etc)
PS:還有許多參數可做設定, 例如檔案大小限制、錯誤訊息, 可參考 (CFileValidator)
重要:
網路上很多範例都會少了allowEmpty這個參數, 就像這篇 Multiple files uploader with CMultiFileUpload.
結果就會非常慘, 就是會發生檔案上傳了, 但是填寫表格的資料一直存不進資料庫. 然後會出現錯誤:XXX cannot be blank, 然後你就會匪夷所思, 明明檔案都上傳了, 檔名也都抓到了, 為什麼就是存不進去.
原來因為我們在model裡設定它是file, 所以它上傳的是檔案, 而不是一個字串 (檔名), 所以我們必須要設allowEmpty這個參數, 告訴model我們允許它是空的, 這樣在save的時候才不會被model的規則給擋住!!!
這部分我卡了好幾天, 真的很重要阿~ 各位.
View
一樣是改_form.php這個檔案 (框架預設), 修改以下的code:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'bnb-form',
'enableClientValidation'=>true,
'htmlOptions' => array('enctype' => 'multipart/form-data'),
)); ?>
<?php
$this->widget('CMultiFileUpload', array(
'model' => $model,
'attribute' => 'bnbImg',
'accept' => 'jpeg|jpg|png',
'duplicate' => '你選過這個照片了喔!',
'denied' => '請選擇jpeg、jpg、png格式的影像!',
'htmlOptions' => array('multiple' => 'multiple'),
'max' => 5,
));
?>
上傳檔案最重要的就是htmlOptions這個參數裡面的設定一定要是'enctype' => 'multipart/form-data'.
至於'enableClientValidation'=>true, 這個非常好用! 它會依你的model的規則設定來生成對應的JavaScript來做Client端的驗證, 超屌. 不過跟上傳檔案沒關係.
1.
attribute會生成HTML input的id跟name. 例如: 我資料表叫Test, 欄位是fuck, 這時候我設定'attribute' => 'fuck', 就會產生以下code:
<input id="Test_fuck" type="file" value="" name="Test[fuck][]" />
2.
accept - 允許的檔案格式
duplicate - 當選到重複的照片時跳出的警告視窗
denied - 當夾帶不是我們規定的檔案格式時, 跳出的警告視窗
'htmlOptions' => array('multiple' => 'multiple') - 可讓你一次選多張
max - 最多可上傳的檔案數量
別懷疑, 做了這些設定, yii就幫你把它生成JavaScript, 讓你爽的死去活來的!!
重要:
有些人會在CActiveForm裡做AJAX, 所以會加上這個 'enableAjaxValidation'=>false,
在表格有檔案上傳的欄位時千萬不要加那個! 因為它會讓你出錯, 以下擷取官方部分內容:
基於AJAX的驗證有一些限制:首先,它不能用於文件上傳字段;其次,它不能用於可能產生服務器端狀態改變的驗證;第三,它目前還不能用於表格式輸入的驗證。
Conrtoller
public function actionCreate()
{
$model = new Bnb;
if(isset($_POST['Bnb']))
{
$model->attributes=$_POST['Bnb'];
/*
$uploadPath Set info:
Linux: /images/bnb/ , Win: \images\bnb\
*/
$uploadPath = DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'bnb' . DIRECTORY_SEPARATOR;
if($allFilesName=$this->uploadMultiFile($model, 'bnbImg', $uploadPath))
$model->bnbImg = implode(",", $allFilesName);
if($model->save())
$this->redirect(array('view', 'id'=>$model->bnbId));
}
$this->render('create',array(
'model'=>$model,
));
}
private function uploadMultiFile($model, $attr, $path)
{
if($fileInfo = CUploadedFile::getInstances($model, $attr))
{
foreach ($fileInfo as $i=>$file)
{
$formatName = $file->name;
$file->saveAs(Yii::getPathOfAlias('webroot') . DIRECTORY_SEPARATOR . $path . $formatName); //webroot: you'r project/protected
$allFilesName[$i] = $formatName;
}
return ($allFilesName);
}
}
1. 用 DIRECTORY_SEPARATOR 是因為路徑在Linux跟windows不一樣的, 所以為了都能正常運做, 就用了比較長的寫法. (參考 DIRECTORY_SEPARATOR的作用)
2. 將上傳的code單獨寫成uploadMultiFile是為了讓整個可讀性更高, 避免程式絮亂, 以方便維護.
Finish~ thx GOD
參考資料:CMultiFileUpload
2014年7月5日 星期六
yii framework - 如何用AJAX來做表單驗證 (client端)
yii真的太猛了!
上次 如何用AJAX來做表單驗證 用的方式是在server端做驗證, 所以用的是
'enableAjaxValidation'=>true,
不過事實上我們很多時候, 是(只)需要用到client端驗證, 那怎麼辦呢?
很簡單! 加上下面的code就可以了!
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
這樣yii就會用jQuery來作client端的驗證了~! 並且沒全部通過還不讓使用者送出喔^^
真的超屌的!!
所以如果有些地方需要很嚴謹的檢查的話, 就可以兩個都加上去, 這樣就可以在server及client端做驗證
上次 如何用AJAX來做表單驗證 用的方式是在server端做驗證, 所以用的是
'enableAjaxValidation'=>true,
不過事實上我們很多時候, 是(只)需要用到client端驗證, 那怎麼辦呢?
很簡單! 加上下面的code就可以了!
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
這樣yii就會用jQuery來作client端的驗證了~! 並且沒全部通過還不讓使用者送出喔^^
真的超屌的!!
所以如果有些地方需要很嚴謹的檢查的話, 就可以兩個都加上去, 這樣就可以在server及client端做驗證
yii framework - 如何用AJAX來做表單驗證 (server端)
在我們使用gii來建立我們的CURD後, 我們可以在Controller最下面看到這個function
protected function performAjaxValidation($model)
{
if(isset($_POST['ajax']) && $_POST['ajax']==='house-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
原來~ yii已經幫我們建立好AJAX的驗證code了!
那我們來實作吧!
STEP 1
在Contorller裡需要用到AJAX的action加上這句:
$this->performAjaxValidation($model);
結果就會像這樣:
public function actionCreate()
{
$model=new Bnb;
$this->performAjaxValidation($model);
if(isset($_POST['Bnb']))
{
$model->attributes=$_POST['House'];
if($model->save())
$this->redirect(array('view', 'id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
));
}
STEP 2
view裡的_form.php打開AJAX服務
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'house-form',
'enableAjaxValidation'=>true,
)); ?>
protected function performAjaxValidation($model)
{
if(isset($_POST['ajax']) && $_POST['ajax']==='house-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
原來~ yii已經幫我們建立好AJAX的驗證code了!
那我們來實作吧!
STEP 1
在Contorller裡需要用到AJAX的action加上這句:
$this->performAjaxValidation($model);
結果就會像這樣:
public function actionCreate()
{
$model=new Bnb;
$this->performAjaxValidation($model);
if(isset($_POST['Bnb']))
{
$model->attributes=$_POST['House'];
if($model->save())
$this->redirect(array('view', 'id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
));
}
STEP 2
view裡的_form.php打開AJAX服務
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'house-form',
'enableAjaxValidation'=>true,
)); ?>
NOTE:
驗證的相關規則是在models裡喔!
ex:
public function rules()
{
return array(
array('adminId, adminPw, 'required'),
array('adminMail', 'email'),
);
}
yii內建的驗證功能如下:(CValidator)
required
|
驗證屬性值必需有值,不能為空
|
filter
|
用過濾器轉換屬性的值
|
match
|
驗證屬性值匹配一個正則表達式
|
email
|
驗證屬性值為有一個有效的Email地址
|
url
|
驗證屬性值是一個有效的URL
|
unique
|
驗證屬性值在表中的對應列中是唯一的
|
compare
|
驗證屬性值與另一個屬性的值相等
|
length
|
驗證屬性值的長度在一個範圍內
|
in
|
驗證屬性值在一個預定義列表中
|
numerical
|
驗證屬性值是數字
|
captcha
|
驗證屬性的值等於一個顯示的CAPTCHA(驗證碼)的值
|
file
|
驗證屬性值包含上傳的文件
|
type
|
驗證屬性值是一個指定的數據類型
|
default
|
驗證屬性值為分配的默認值
|
exist
|
驗證屬性值在表中的對應列中存在
|
boolean
|
驗證屬性值是布爾值(true或false)
|
safe
|
標記屬性值為安全
|
unsafe
|
標記屬性值為不安全
|
date
|
驗證屬性值是日期
|
標籤:
AJAX,
CValidator,
enableAjaxValidation,
rules
2014年7月4日 星期五
yii framework - 如何上傳照片 (單張)? 使用CUploadedFile
要實現照片上傳功能, 需在model、conrtoller、view三個地方逐一修改才能完成,
我會逐一說明 (以M->V->C的順序).
本次實作的目標:
將照片上傳至指定資料夾, 並將照片的檔名存到資料庫, 以便之後取用.
Model
在你的models裡的rules()新增以下code:
array('dbFieldsOfTheImage', 'file', 'types'=>'jpg, gif, png'),
1. 請將這邊的dbFieldsOfTheImage改為你照片上傳的資料表欄位名稱
2. types指的是, 指定的上傳檔案類型 (如果你要讓人上傳的是excel, 那就打上xls, xlsx...etc)
PS:還有許多參數可做設定, 例如檔案大小限制、錯誤訊息, 可參考 (CFileValidator)
View
看看你的controller新增、修改對應的view, 會發現表單的實體是在_form.php這個檔案 (框架預設),
進到_form.php後修改以下code:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'bnb-form',
'enableAjaxValidation'=>false,
'htmlOptions' => array('enctype' => 'multipart/form-data'), <-新增這行
)); ?>
然後在新增這段, 才會有上傳的按鈕出現
<div class="row">
<?php echo $form->labelEx($model,'dbFieldsOfTheImage'); ?>
<?php echo $form->fileField($model,'dbFieldsOfTheImage'); ?>
<?php echo $form->error($model,'dbFieldsOfTheImage'); ?>
</div>
注意第二個的fileField, 在yii的框架預設下是textField (文字框), 要改成fileField.
Conrtoller
我會逐一說明 (以M->V->C的順序).
本次實作的目標:
將照片上傳至指定資料夾, 並將照片的檔名存到資料庫, 以便之後取用.
Model
在你的models裡的rules()新增以下code:
array('dbFieldsOfTheImage', 'file', 'types'=>'jpg, gif, png'),
1. 請將這邊的dbFieldsOfTheImage改為你照片上傳的資料表欄位名稱
2. types指的是, 指定的上傳檔案類型 (如果你要讓人上傳的是excel, 那就打上xls, xlsx...etc)
PS:還有許多參數可做設定, 例如檔案大小限制、錯誤訊息, 可參考 (CFileValidator)
View
看看你的controller新增、修改對應的view, 會發現表單的實體是在_form.php這個檔案 (框架預設),
進到_form.php後修改以下code:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'bnb-form',
'enableAjaxValidation'=>false,
'htmlOptions' => array('enctype' => 'multipart/form-data'), <-新增這行
)); ?>
然後在新增這段, 才會有上傳的按鈕出現
<div class="row">
<?php echo $form->labelEx($model,'dbFieldsOfTheImage'); ?>
<?php echo $form->fileField($model,'dbFieldsOfTheImage'); ?>
<?php echo $form->error($model,'dbFieldsOfTheImage'); ?>
</div>
注意第二個的fileField, 在yii的框架預設下是textField (文字框), 要改成fileField.
Conrtoller
public function actionCreate()
{
$model=new House;
if(isset($_POST['House']))
{
$model->attributes=$_POST['House'];
$imageUploadFile = CUploadedFile::getInstance($model,'houseImg');
$fileName = $imageUploadFile->name;
$model->bnbImg = $fileName;
if($model->save())
$file_path = Yii::app()->basePath.'/../images/house/' . $fileName;
$imageUploadFile->saveAs($file_path);
$this->redirect(array('view', 'id'=>$model->bnbId));
}
$this->render('create',array(
'model'=>$model,
));
}
1. 使用CUploadedFile::getInstance為一個模型屬性生成一個文件輸入框
2. $imageUploadFile->name可以取得檔名 (連同副檔名)
3. saveAs是將上傳的照片從上傳的暫存區移到指定的目錄 (記得要目錄+檔名喔!)
PS:
1. Yii::app()->basePath是取得網站的protected資料夾位置, 如果你的網站建置時取名www, 那就會返回 - 網站在主機的路徑/www/protected. 所以如果你的照片位置在網站根目錄下的images, 那就要用".."返回到上一層, 並進到images資料夾. ex: Yii::app()->basePath.'/../images/
其實用 Yii::getPathOfAlias('webroot')就可以直接取得網站專案名/protected的路徑 - 2014.7.6 補充
2. 測試後發現上傳的資料夾要先建立好, 要不然會出錯 (如果有需要可以自己寫一個建資料夾的程式)
1. Yii::app()->basePath是取得網站的protected資料夾位置, 如果你的網站建置時取名www, 那就會返回 - 網站在主機的路徑/www/protected. 所以如果你的照片位置在網站根目錄下的images, 那就要用".."返回到上一層, 並進到images資料夾. ex: Yii::app()->basePath.'/../images/
其實用 Yii::getPathOfAlias('webroot')就可以直接取得網站專案名/protected的路徑 - 2014.7.6 補充
2. 測試後發現上傳的資料夾要先建立好, 要不然會出錯 (如果有需要可以自己寫一個建資料夾的程式)
2014年6月30日 星期一
yii framework - [UI] 如何變更CGridView的檢視、修改、刪除icon及超連結?
先來看段code:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'user-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'name',
'phone',
array(
'class'=>'CButtonColumn',
'template'=>'{lookMyDetail} {justUpdate} {deleteMe}',
'buttons'=>array
(
'lookMyDetail' => array
(
'label'=>'來看我的一切秘密吧',
'imageUrl'=>Yii::app()->request->baseUrl . '/images/icons/view.png',
'url'=>'Yii::app()->createUrl("user/detail", array("id"=>$data->id))',
),
'justUpdate' => array
(
'label'=>'就是要改怎樣?',
'imageUrl'=>Yii::app()->request->baseUrl . '/images/icons/update.png',
'url'=>'Yii::app()->createUrl("user/adminUpdate", array("id"=>$data->id))',
),
'deleteMe' => array
(
'label'=>'刪掉我的記憶',
'imageUrl'=>Yii::app()->request->baseUrl . '/images/icons/delete.png',
'url'=>'Yii::app()->createUrl("user/delete", array("id"=>$data->id))',
),
),
),
),
));
?>
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'user-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'name',
'phone',
array(
'class'=>'CButtonColumn',
'template'=>'{lookMyDetail} {justUpdate} {deleteMe}',
'buttons'=>array
(
'lookMyDetail' => array
(
'label'=>'來看我的一切秘密吧',
'imageUrl'=>Yii::app()->request->baseUrl . '/images/icons/view.png',
'url'=>'Yii::app()->createUrl("user/detail", array("id"=>$data->id))',
),
'justUpdate' => array
(
'label'=>'就是要改怎樣?',
'imageUrl'=>Yii::app()->request->baseUrl . '/images/icons/update.png',
'url'=>'Yii::app()->createUrl("user/adminUpdate", array("id"=>$data->id))',
),
'deleteMe' => array
(
'label'=>'刪掉我的記憶',
'imageUrl'=>Yii::app()->request->baseUrl . '/images/icons/delete.png',
'url'=>'Yii::app()->createUrl("user/delete", array("id"=>$data->id))',
),
),
),
),
));
?>
紅色字就是特別要注意的地方!
1. 首先columns是你要顯示的欄位
2. CButtonColumn就是為了後面的按鈕所呼叫的class
3. template非常重要!! 這裡預設是{view} {update} {delete}, 分別代表三個按鈕的順序及超連結目標.
例如:
如果我只想要刪除、修改的話, 那就是 {delete} {update}, 這樣就不會有檢視 (view的圖案跟連結), 而且順序也改變了!
再進階點:
那就是如上面的例子, 透過設置buttons的array參數來添加
1. 滑鼠移過去時的文字提示 (label)
2. 圖示 (imageUrl)
3. 超連結的網址 (url)
這樣就可以符合我們的基本需求了吧^^ 來睡嘍~
標籤:
CButtonColumn,
CGridView,
template
yii framework - [UI] 如何修改CListView的id連結?
一般我們會在view裡看到這段code
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider' => $dataProvider,
'itemView' => '_view',
)); ?>
然後我們會看到一個把db"部分"資料列出來的表格, 第一欄的id預設的超連結是xxx/view
但是我要改成detail要怎麼改呢?
本來以為要改變id的超連結要設定CListView的參數, 但是查半天都沒看到...
最後原來要修改的東西是在_view.php這個檔案裡...暈
<b><?php echo CHtml::encode($data->getAttributeLabel('bnbId')); ?>:</b>
<?php echo CHtml::link(CHtml::encode($data->bnbId), array('view', 'id'=>$data->bnbId)); ?>
<br />
把view改成detail就搞定了!! 就這麼簡單...睡覺去zzzz
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider' => $dataProvider,
'itemView' => '_view',
)); ?>
然後我們會看到一個把db"部分"資料列出來的表格, 第一欄的id預設的超連結是xxx/view
但是我要改成detail要怎麼改呢?
本來以為要改變id的超連結要設定CListView的參數, 但是查半天都沒看到...
最後原來要修改的東西是在_view.php這個檔案裡...暈
<b><?php echo CHtml::encode($data->getAttributeLabel('bnbId')); ?>:</b>
<?php echo CHtml::link(CHtml::encode($data->bnbId), array('view', 'id'=>$data->bnbId)); ?>
<br />
把view改成detail就搞定了!! 就這麼簡單...睡覺去zzzz
2014年6月24日 星期二
yii framework - [UI] 按鈕超連結設定linkButton、CJuiButton
如果要單純生成一個具有超連結功能的按鈕, 並且可以傳值, 有幾種方式:
這是常用的兩種 linkButton跟CJuiButton
CHtml::linkButton('變更', array(
'submit'=>array('food/update', 'id'=>$model->id)
));
$this->widget('zii.widgets.jui.CJuiButton', array(
'buttonType'=>'link',
'name'=>'update',
'caption'=>'變更',
'url'=>array('food', 'id'=>$model->id),
));
linkButton (官方說明)
會生成一個一般的超連結, 不過他並不會大剌剌的將你的參數跟值秀出來
(ex: index.php?r=food/update&id=xxxxx)
CJuiButton (官方說明)
由於這是yii封裝了jQueryui, 所以它會生成一個很漂亮的按鈕樣式, 並且提供許多實用的功能
不過他會大剌剌的將你的參數跟值秀出來
CHtml提供了一般前端會需要的一些東西, 例如:
tag、textArea、form、button、radio....等
而CJuiWidget則封裝了jQueryui, 所以jQueryui的東西都可以直接用, 真的是很方便
這是常用的兩種 linkButton跟CJuiButton
CHtml::linkButton('變更', array(
'submit'=>array('food/update', 'id'=>$model->id)
));
$this->widget('zii.widgets.jui.CJuiButton', array(
'buttonType'=>'link',
'name'=>'update',
'caption'=>'變更',
'url'=>array('food', 'id'=>$model->id),
));
linkButton (官方說明)
會生成一個一般的超連結, 不過他並不會大剌剌的將你的參數跟值秀出來
(ex: index.php?r=food/update&id=xxxxx)
CJuiButton (官方說明)
由於這是yii封裝了jQueryui, 所以它會生成一個很漂亮的按鈕樣式, 並且提供許多實用的功能
不過他會大剌剌的將你的參數跟值秀出來
CHtml提供了一般前端會需要的一些東西, 例如:
tag、textArea、form、button、radio....等
而CJuiWidget則封裝了jQueryui, 所以jQueryui的東西都可以直接用, 真的是很方便
標籤:
CJuiButton,
linkButton,
yii
2014年6月20日 星期五
yii framework - 分頁功能要怎麼做? 運用CPagination+CLinkPager
分頁是一個網站的常見功能, 所以勢必要學會如何使用! 那我們開始吧!
首先是Controller的部分:
說明:
function actionIndex(){ $criteria = new CDbCriteria(); $count=Article::model()->count($criteria); $pages=new CPagination($count); $pages->pageSize=10; $pages->applyLimit($criteria); $models = Post::model()->findAll($criteria); $this->render('index', array( 'models' => $models, 'pages' => $pages )); }
1. CDbCriteria把你要抓的資料條件都設好 ( 查詢資料大解密之"CDbCriteria到底是什麼? )
2. count得到符合條件的資料筆數
3. 把得到的資料筆數丟到CPagination裡
4. pageSize設定每個分頁要顯示幾筆
6. 將$pages渲染 (render)到view去
標籤:
applyLimit,
CDbCriteria,
CLinkPager,
CPagination,
pageSize,
yii
2014年6月12日 星期四
Swift-中文導覽手冊
相信很多人都在Apple的WWDC 2014看到這個新語言, 並且躍躍欲試.
但是官方的文件是英文的阿! 雖然說身為一位程式設計師要有一定的讀英文能力啦~
不過如果有中文版的勢必會加速大家在新語言的學習速度阿!
小第剛好爬到由許多大大共同完成的Swift中文版, 並公開分享 (實在偉大)
下面就是Swift的中文版導覽手冊:
https://www.gitbook.com/book/tommy60703/swift-language-traditional-chinese/details
但是官方的文件是英文的阿! 雖然說身為一位程式設計師要有一定的讀英文能力啦~
不過如果有中文版的勢必會加速大家在新語言的學習速度阿!
小第剛好爬到由許多大大共同完成的Swift中文版, 並公開分享 (實在偉大)
下面就是Swift的中文版導覽手冊:
https://www.gitbook.com/book/tommy60703/swift-language-traditional-chinese/details
2014年5月17日 星期六
yii framework - 如何一次寫入多筆資料?
假設現在要購買一台車, 車的紀錄有顏色跟最高時速 (饒了我~ 我比較懶~先舉這兩個就好),
並且我們有個購物車清單陣列來紀錄所有要買的車.
一般我們新增 (insert)單筆資料時用的方法是 save(), 例如:
$car=new Car;
$car->color=$color;
$car->maxSpeed=$speed;
if($car->save ()){
echo "新增成功";
}else{
echo "新增失败";
}
$car=new Car;
$car->color=$color;
$car->maxSpeed=$speed;
if($car->save ()){
echo "新增成功";
}else{
echo "新增失败";
}
但是當我們要新增多筆的時候呢? 例如:
標籤:
getIsNewRecord,
insert,
save,
setIsNewRecord,
yii
2014年5月2日 星期五
yii framework - 如何使用某個資料夾的php function呢?
假設我們今天要在專案下新增一個資料夾 (ex: Tools)來統一管理我們寫的function
(ex: test.php裡的function showMyName)時, 要怎麼做呢?
test.php
<?php
class Custom
{
publice function showMyName($name)
{
return $name;
}
}
?>
(ex: test.php裡的function showMyName)時, 要怎麼做呢?
test.php
<?php
class Custom
{
publice function showMyName($name)
{
return $name;
}
}
?>
2014年4月28日 星期一
yii framework - 如何多個Controller共用一個filter?
我們都知道Yii可以跨Controller使用function (ex: UserController::ShowHallo), 但是很多時候我們會希望一個過濾器(filter)能讓許多的Controller共用.
因為我們不用再重複寫一樣的cord, 是吧! 正如《Clean Code》的Bob大叔說的:不要重複自己DRY (Don't Repeat Yourself)
步驟:
1. 在protected/下建立一個資料夾 (ex: filers)
2. 在protected/filers下建立一個檔案 (ex: ShowHalloFilter.php)
3. 幫你的filter寫點東西
4. 在要使用的Controller裡的filers用array ('application.filters.ShowHalloFilter + aboutMe, fuckYou')的方式來使用我們建立的filter
因為我們不用再重複寫一樣的cord, 是吧! 正如《Clean Code》的Bob大叔說的:不要重複自己DRY (Don't Repeat Yourself)
步驟:
1. 在protected/下建立一個資料夾 (ex: filers)
2. 在protected/filers下建立一個檔案 (ex: ShowHalloFilter.php)
3. 幫你的filter寫點東西
4. 在要使用的Controller裡的filers用array ('application.filters.ShowHalloFilter + aboutMe, fuckYou')的方式來使用我們建立的filter
2014年4月21日 星期一
yii framework - 為什麼Facebook登出會轉到home.php
問題:
為什麼在登出fb的時候沒有轉到自己所指定的頁面, 而是跑到Facebook的home.php?
可能的原因:
1. 你的登出後要轉到(next)的網址錯誤, 例如:
$params = array( 'next' => 'http://www.test.com/index.html' );
$logout_url = Yii::app()->facebook->getLogoutUrl($params);
如果你是index.php, 而不是index.html的話就會發生這個現象!
2. 你沒有拿到正確的access token
2. 你沒有拿到正確的access token
其實檢查方式很簡單, 你可以把上面的$logout_url echo出來, 就可以知道到底getLogoutUrl()這個函式到底都產生了什麼鬼.
2014年3月22日 星期六
yii framework - 如何使用Facebook登入(Facebook PHP SDK)
本篇是使用Facebook API PHP SDK, 如果是要用JavaScript SDK的人可以直接搜尋"JavaScript SDK facebook"就有非常多資訊了! 或是參考這篇:facebook程式設計-JavaScript SDK
許多開發者都會經歷一個階段, 就是讓使用者可以用FB登入->註冊
到底在yii framework要如何實現呢? 在這Joker就分享一下自己的開發過程及心得:
首先我先講一下, 網路上很多都使用JavaScript SDK, 這讓我很困惑. 困惑的點是我到底該使用哪個呢? PHP or JavaScript SDK?
其實兩邊的寫法都不難, 只是一個寫在客戶端、一個是在伺服端罷了!
後來我想到有關於資訊安全上的問題, 所以試著去找一下, 有沒有相關的資料來印證我對於JavaScript安全性的顧慮, 後來我找到這篇, 大家可以看一下:網站利用 Facebook 帳號登入 (使用 OAuth)
標籤:
Facebook,
facebook登入,
PHP SDK,
yii
2014年2月28日 星期五
yii framework - Warning: Cannot modify header information要怎麼解決?
你如果看到這問題表示你一定是在Cookie的地方出問題了!
簡單的說, 就是你在寫入Cookie前有東西輸出了(ex: echo xxx or print_r (xxx))
我自己本身是前面有東西echo了, 所以移除掉就好了!
裡面有人提到修改php.ini, 將output_buffering 設為 On
不過這要看你是否有權限可以進到裡面修改, 這就要看你的主機商了!
2014年2月19日 星期三
yii framework - 抓出全部資料後如何取其中一個欄位的資料?
舉個例子:
假設我們用find抓符合條件的第一筆資料的話, 如下
$criteria=new CDbCriteria;
$criteria>select='id,pw,name,about';
$criteria->compare('loginId',$id);
$detail=RoomType::model()->find($criteria);
我們要如何取其中的id呢?
答案就是:
$detail->id
沒錯! 看到這相信大家就知道要用物件導向的方式來取得了吧!
那如果是用findAll的話呢?
標籤:
CDbCriteria,
compare,
find,
findAll,
yii
訂閱:
文章 (Atom)