Archive for category program
Yii 1.1 CActiveRecord 關連的部份修正
剛剛用Yii 的AR 寫的很開心,
下了這個
$criteria=new CDbCriteria;
$criteria->condition='products.id=:ID AND products_info.language_id=:languageID';
$criteria->params=array(':ID'=>$_GET['id'], ':languageID' => $this->_lang_id );
$criteria->order = 'products_content.content_orders ASC';
$model = Products::model()->with( 'products_info', 'products_content' )->find( $criteria );
一直出現
CDbCommand 無法執行 SQL 陳述: SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘products.id’ in ‘where clause’
想說怪了…
再看了一下 sql log
543 Query SELECT `t`.`id` AS `t0_c0`, `products_info`.`products_id` AS `t1_c0`, `products_info`.`language_id` AS `t1_c1`, `products_info`.`name` AS `t1_c2`, `products_info`.`content` AS `t1_c3`, `products_content`.`id` AS `t2_c0`, `products_content`.`products_id` AS `t2_c1`, `products_content`.`language_id` AS `t2_c2`, `products_content`.`content_name` AS `t2_c3`, `products_content`.`content_value` AS `t2_c4`, `products_content`.`content_orders` AS `t2_c5` FROM `products` `t` LEFT OUTER JOIN `products_info` `products_info` ON (`products_info`.`products_id`=`t`.`id`) LEFT OUTER JOIN `products_content` `products_content` ON (`products_content`.`products_id`=`t`.`id`) WHERE (products.id='1' AND products_info.language_id='1') ORDER BY products_content.content_orders ASC
發現Products model 變成t 了
想說很怪
再去看了一下 1.1 CHANGELOG
發現了這段..
The alias name for the primary table in a relational AR query is changed to be ‘t’ (Qiang)
好吧乖乖的把products.id改成t.id
Yii Csort With ActiveRecord
controller 部份
$sort->attributes= array(
'product.id'=>'productId',
'product.name'=>'productName',
'category.name'=>'categoryName',
'brand.name' => 'brandName',
);
/*
$sort->attributes= array(
'model中的alias.欄位'=>'網址顯示的Alias',
);
*/
view 部份
< ?php echo $sort->link('product.id','編號'); ?>
//< ?php echo $sort->link('table.name','網頁顯示的名稱'); ?>
model 部份
記得把 relations中的 alias 設好
如下
/**
* @return array relational rules.
*/
public function relations()
{
return array(
'brand'=>array(self::BELONGS_TO,'brand','brand_id', 'alias'=>'brand'),
'category'=>array(self::BELONGS_TO,'category','category_id', 'alias'=>'category'),
'series'=>array(self::BELONGS_TO,'series','series_id','alias'=>'series'),
);
}
system() & exec()
system()
The system() call also tries to automatically flush the web server’s output buffer after each line of output if PHP is running as a server module.
exec()
則不會flush
遇到的問題是
我的php 透過perl 去執行一些功能
然後perl 回傳 success or false 字串 在standard output 上
php再去get 這個字串
success 則print success
給 ajax 來判斷
結果 在前端的ajax 一直印出 successsuccess
的字眼
想說怎麼會印兩次….
看了一下手冊才發現這個
之前就想說 php 幹麻沒事有兩個 執行CLI 的東西……
仔細看了一下手冊才知道
筆記一下..
YUI RTE setEditorHTML….
var myEditor = new YAHOO.widget.Editor('editor', config);
myEditor.on('editorContentLoaded', function() {
myEditor.setEditorHTML('This is my new content');
});
myEditor.render();
要 listening editorContentLoaded event 才行
沒在editorContentLoaded 裡下………….
myEditor.setEditorHTML(‘This is my new content’);
沒作用………
some YUI RTE note..
在<body> 這個tag 似乎一定要設
class=’yui-skin-sam’
不然會有一些小問題
我之前是設在<div class=’yui-skin-sam’><textarea></textarea></div>
這樣來解 ..不過…
用了一陣子才發現….class=’yui-skin-sam’不是設在body 的話….
add link 的這個func 會破版…………..css 會整個走掉….
本來是沒有很想加 class 在body 的..
不過突然想到….drupal 的 plugin 中也有yui rte
我就去看了一下他是怎麼解的..
<script type="text/javascript">
if (Drupal.jsEnabled) { $(document).ready(function() { $('body').addClass('yui-skin-sam'); } ); };
</script>
然後看了一下skin裡面的css 應該是不至於加了這個class 造成新版的走位,所以就照著幹了…
YUI Rich Text Editor 小記
因為有打算用YUI RTE 來做default 的editor
不過因為有想要在textarea 裡面加入content 的須求
用document.post_form.post_text.value
會沒辦法在”所見即所得模式”下有反應
只能在原始碼模式下有作用
翻了一下文件
要用cmd_inserthtml來做
如下
myEditor = YAHOO.widget.EditorInfo.getEditorById('post_text');
myEditor.execCommand('inserthtml', document.post_form.post_text.value);
這樣應該就搞定了…
php preg_replace bug ??
這個問題在在Zend Framework 中
Zend/Db/Statement.php
裡面
[cc lang="php" tab_size="2" lines="40"]
protected function _stripQuoted($sql)
{
// get the character for delimited id quotes,
// this is usually ” but in MySQL is `
$d = $this->_adapter->quoteIdentifier(‘a’);
$d = $d[0];
// get the value used as an escaped delimited id quote,
// e.g. \” or “” or \`
$de = $this->_adapter->quoteIdentifier($d);
$de = substr($de, 1, 2);
$de = str_replace(‘\\’, ‘\\\\’, $de);
// get the character for value quoting
// this should be ‘
$q = $this->_adapter->quote(‘a’);
$q = $q[0];
// get the value used as an escaped quote,
// e.g. \’ or ”
$qe = $this->_adapter->quote($q);
$qe = substr($qe, 1, 2);
$qe = str_replace(‘\\’, ‘\\\\’, $qe);
// get a version of the SQL statement with all quoted
// values and delimited identifiers stripped out
// remove “foo\”bar”
$sql = preg_replace(“/$q($qe|\\\\{2}|[^$q])*$q/”, ”, $sql);
// remove ‘foo\’bar’
if (!empty($q)) {
$sql = preg_replace(“/$q($qe|[^$q])*$q/”, ”, $sql);
}
return $sql;
}
[/cc]
發現的
我是要執行一段db->query($sql)
sql 是 insert into xxx
有把sql 單純的print 出來到mysql 中執行是可以成功執行的
trace 到最後發現會卡在preg_replace這邊
而看httpd error , access log 都沒有訊息
看message log 就會出現
Nov 12 13:22:33 mail kernel: pid 50728 (httpd), uid 80: exited on signal 4
所以判斷應該是
php 的bug
我的解法是不用preg_replace 換成
ereg_replace, mb_ereg_replace
都可以.
Zend Framework DB Load Balancing (Master/Slave Database)
網路上找來找去……
沒看到有人寫相關的解法….
加上不想用mysql-proxy來解這部份…
所以打算從code 的部份下手
看到最後只能動Zend Framework 的code 了(還沒想到可以不動ZF 的code 而做到DB LB的方法)
我是先從function save 下手去找..
Zend/Table/Row/Abstract.php: public function save()
public function save()
{
/**
* If the _cleanData array is empty,
* this is an INSERT of a new row.
* Otherwise it is an UPDATE.
*/
if (empty($this->_cleanData)) {
return $this->_doInsert();
} else {
return $this->_doUpdate();
}
}
ZF會自已做update or insert 的區分
再看
/**
* @return mixed The primary key value(s), as an associative array if the
* key is compound, or a scalar if the key is single-column.
*/
protected function _doInsert()
{
/**
* A read-only row cannot be saved.
*/
if ($this->_readOnly === true) {
require_once 'Zend/Db/Table/Row/Exception.php';
throw new Zend_Db_Table_Row_Exception('This row has been marked read-only');
}
/**
* Run pre-INSERT logic
*/
$this->_insert();
/**
* Execute the INSERT (this may throw an exception)
*/
$data = array_intersect_key($this->_data, $this->_modifiedFields);
$primaryKey = $this->_getTable()->insert($data);
/**
* Normalize the result to an array indexed by primary key column(s).
* The table insert() method may return a scalar.
*/
if (is_array($primaryKey)) {
$newPrimaryKey = $primaryKey;
} else {
$newPrimaryKey = array(current((array) $this->_primary) => $primaryKey);
}
/**
* Save the new primary key value in _data. The primary key may have
* been generated by a sequence or auto-increment mechanism, and this
* merge should be done before the _postInsert() method is run, so the
* new values are available for logging, etc.
*/
$this->_data = array_merge($this->_data, $newPrimaryKey);
/**
* Run post-INSERT logic
*/
$this->_postInsert();
/**
* Update the _cleanData to reflect that the data has been inserted.
*/
$this->_refresh();
return $primaryKey;
}
$primaryKey = $this->_getTable()->insert($data);
程式在
Zend/Adapter/Abstract.php
這邊有
function update()
function insert()
來看
public function insert($table, array $bind)
{
// extract and quote col names from the array keys
$cols = array();
$vals = array();
foreach ($bind as $col => $val) {
$cols[] = $this->quoteIdentifier($col, true);
if ($val instanceof Zend_Db_Expr) {
$vals[] = $val->__toString();
unset($bind[$col]);
} else {
$vals[] = '?';
}
}
// build the statement
$sql = "INSERT INTO "
. $this->quoteIdentifier($table, true)
. ' (' . implode(', ', $cols) . ') '
. 'VALUES (' . implode(', ', $vals) . ')';
// execute the statement and return the number of affected rows
$stmt = $this->query($sql, array_values($bind));
$result = $stmt->rowCount();
return $result;
}
不管insert or update
都是透過query 這個method 去執行sql
所以就在這邊下手吧
public function query($sql, $bind = array())
{
// connect to the database if needed
if ($sql instanceof Zend_Db_Select) {
if (preg_match('/UPDATE|INSERT|REPLACE/i',$sql->__toString())) {
$this->closeConnection();
$this->_config['dbname'] = 'DB_WRITE';
}
} else {
if (preg_match('/UPDATE|INSERT|REPLACE/i',$sql)) {
$this->closeConnection();
$this->_config['dbname'] = 'DB_WRITE';
}
}
$this->_connect();
// is the $sql a Zend_Db_Select object?
if ($sql instanceof Zend_Db_Select) {
$sql = $sql->assemble();
}
// make sure $bind to an array;
// don't use (array) typecasting because
// because $bind may be a Zend_Db_Expr object
if (!is_array($bind)) {
$bind = array($bind);
}
// prepare and execute the statement with profiling
$stmt = $this->prepare($sql);
$stmt->execute($bind);
// return the results embedded in the prepared statement object
$stmt->setFetchMode($this->_fetchMode);
if ($sql instanceof Zend_Db_Select) {
if (preg_match('/UPDATE|INSERT|REPLACE/i',$sql->__toString())) {
$this->closeConnection();
$this->_config['dbname'] = 'DB_READ';
$this->_connect();
}
} else {
if (preg_match('/UPDATE|INSERT|REPLACE/i',$sql)) {
$this->closeConnection();
$this->_config['dbname'] = 'DB_READ';
$this->_connect();
}
}
return $stmt;
}
就是很簡單的去parse $sql 是否有UPDATE,INSERT,REPLACE 之類的寫入語法
若有的話就改config
基本上就是這樣…
如果有人有更好的做法…
拜拖 指教一下小第………..
實在是不想弄到ZF 裡面的code 來達到DB LB的功能..
PHP Universal Feed Generator 中文問題..
之前忘了在那看到這個 PHP Universal Feed Generator 感覺還滿好用的…
結果就在這幾天要用的時後…
發現他中文在轉碼的時後有問題…
trace 一下他的code 發現是298 行的
htmlentities($tagContent);這個的問題
把他換成
htmlentities($tagContent, ENT_COMPAT, ‘utf-8′);
應該就可以了
另外看了一下他在header 的部份沒有宣告是UTF8
所以我也修改了一下….
在84 行
header(“Content-type: text/xml”);
改一下
header(“Content-type: text/xml; charset=UTF-8″);
基本上這樣應該就可以了…
php 找出日期的差距天數
記得先compile calendar 這個php extension 才會有
gregoriantojd 這個function..
http://roshanbh.com.np/2008/03/finding-days-difference-php.html
PS
之前都是自已硬幹…..
用mktime date轉來轉去才算出來的…