方法 bindParam() 和 bindValue() 非常相似。
唯一的区别就是前者使用一个PHP变量绑定参数,而后者使用一个值。
所以使用bindParam是第二个参数只能用变量名,而不能用变量值,而bindValue至可以使用具体值。
$stm = $pdo->prepare("select * from users where user = :user");
$user = "jack";
//正确
$stm->bindParam(":user",$user);
//错误
//$stm->bindParam(":user","jack");
//正确
$stm->bindValue(":user",$user);
//正确
$stm->bindValue(":user","jack");
另外在存储过程中,bindParam可以绑定为input/output变量,如下面:
$stm = $pdo->prepare("call func(:param1)");
$param1 = "abcd";
$stm->bindParam(":param1",$param1); //正确
$stm->execute();
存储过程执行过后的结果可以直接反应到变量上。
对于那些内存中的大数据块参数,处于性能的考虑,应优先使用前者。
实际开发中会经常碰到,很多人直接先strip_tags过滤掉html标签,但是就只剩下纯文本了,可读性非常差,下面是一个函数
/**
* 截取HTML,并自动补全闭合
* @param $html
* @param $length
* @param $end
*/
function subHtml($html,$length) {
$result = '';
$tagStack = array();
$len = 0;
$contents = preg_split("~(<[^>]+?>)~si",$html, -1,PREG_SPLIT_NO_EMPTY| PREG_SPLIT_DELIM_CAPTURE);
foreach($contents as $tag)
{
if (trim($tag)=="") continue;
if(preg_match("~<([a-z0-9]+)[^/>]*?/>~si",$tag)){
$result .= $tag;
}else if(preg_match("~</([a-z0-9]+)[^/>]*?>~si",$tag,$match)){
if($tagStack[count($tagStack)-1] == $match[1]){
array_pop($tagStack);
$result .= $tag;
}
}else if(preg_match("~<([a-z0-9]+)[^/>]*?>~si",$tag,$match)){
array_push($tagStack,$match[1]);
$result .= $tag;
}else if(preg_match("~<!--.*?-->~si",$tag)){
$result .= $tag;
}else{
if($len + mstrlen($tag) < $length){
$result .= $tag;
$len += mstrlen($tag);
}else {
$str = msubstr($tag,0,$length-$len+1);
$result .= $str;
break;
}
}
}
while(!empty($tagStack)){
$result .= '</'.array_pop($tagStack).'>';
}
return $result;
}
/**
* 截取中文字符串
* @param $string 字符串
* @param $start 起始位
* @param $length 长度
* @param $charset 编码
* @param $dot 附加字串
*/
function msubstr($string, $start, $length,$dot='',$charset = 'UTF-8') {
$string = str_replace(array('&', '"', '<', '>',' '), array('&', '"', '<', '>',' '), $string);
if(strlen($string) <= $length) {
return $string;
}
if(strtolower($charset) == 'utf-8') {
$n = $tn = $noc = 0;
while($n < strlen($string)) {
$t = ord($string[$n]);
if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
$tn = 1; $n++;
} elseif(194 <= $t && $t <= 223) {
$tn = 2; $n += 2;
} elseif(224 <= $t && $t <= 239) {
$tn = 3; $n += 3;
} elseif(240 <= $t && $t <= 247) {
$tn = 4; $n += 4;
} elseif(248 <= $t && $t <= 251) {
$tn = 5; $n += 5;
} elseif($t == 252 || $t == 253) {
$tn = 6; $n += 6;
} else {
$n++;
}
$noc++;
if($noc >= $length) {
break;
}
}
if($noc > $length) {
$n -= $tn;
}
$strcut = substr($string, 0, $n);
} else {
for($i = 0; $i < $length; $i++) {
$strcut .= ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i];
}
}
return $strcut.$dot;
}
/**
* 取得字符串的长度,包括中英文。
*/
function mstrlen($str,$charset = 'UTF-8'){
if (function_exists('mb_substr')) {
$length=mb_strlen($str,$charset);
} elseif (function_exists('iconv_substr')) {
$length=iconv_strlen($str,$charset);
} else {
preg_match_all("/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/", $text, $ar);
$length=count($ar[0]);
}
return $length;
}
今天又摸了下cakephp,突然想研究一下cakephp中modle所提供的findbyfieldname..这样的方法,深入研究了一下,又发现了php的一个新技能!这确实是一个很有魔力的东西,简单代码如下
class OverLoadable{
//这个方法,当调用类中不存在的的方法时会调用这个方法,php自动把这个不存在的方法名和这个方法里的变量数组填充进这个方法并自动调用,于是我要findbyUsername时, 我就可以简单的通过正则提取出方法名中的Username这个字符串,然后传递给类中真正存在的方法findbyfield($field),这样就间接的实现了findbyUsername方法
于是这里,我就可以通过正则提出出方法名
function __call($method, $params){
if(preg_match(“/findby(?P.*)/i”,$method,$preg))
return $this->findbyfield($preg['field']);
}
function findbyfield($field)
{
echo $field;
}
//当读取类的成员变量不存在时,触发这个方法,以你要读取的变量名作为参数
function __get($name){
echo “Your val is $name,and is not exsit in this class!”;
}
//当写入类的成员变量不存在时,触发这个方法,以你要写入的变量名和值作为参数
function __set($name,$value){
echo ‘Your val is ‘.$name.’=>’.$value;
}
}
$oo = new OverLoadable();
$oo->findbyusername();
$oo->i = 5;
?>
论坛上的一个网友提出的问题,在ascii编码的php文件中,定义的一个函数,简单描述如下:
function checkpost()
{
global $subject
$censoww=array(‘婊”);
preg_match(‘/’ . implode(‘|’, $censoww) . ‘/i’, $subject,$matches) ) { echo “非法内容”;}
这是一个简单的禁字检测程序,广泛应用在bbs等程序中.可是这里出现了个问题,但$subject=’存活’ 或者 ‘存货’等时,这个程序竟然也提示非法内容。首先我提倡在程序中统一使用utf-8编码,当然这个程序在utf-8编码下应该没有问题的,可是在ascii下,就会有一些奇怪的bug。这位网页的程序都是基于gbk的,不可能全部转码,只能打打补丁了,下面是简单的解决方案:
mb_internal_encoding(‘gbk’);//指定网络编码为gbk,这同时也作为正则匹配的编码
function checkpost()
{
global $subject
$censoww=array(‘婊”);
//这里使用mb_eregi 代替preg_match,mb_eregi本身支持多字节的正则匹配
if(mb_eregi( implode(‘|’, $censoww) , $subject,$matches) ) { echo “非法内容”;}
顺便翻译了下手册中关于这个函数的简单说明
mb_eregi() executes the regular expression match with multibyte support, and returns 1 if matches are found. This function ignore case. If the optional third parameter was specified, the function returns the byte length of matched part, and the array regs will contain the substring of matched string.
mb_eregi(),支持忽略大小写的多字节正则匹配,如果匹配成功,返回1,如果指定第三个可选参数,函数就返回匹配部分字节数,同时把所有匹配到的子串放在第三个参数指定的数组变量中
list — 把数组中索引对应的值赋给一些变量
void list ( mixed varname, mixed … )
注: list() 仅能用于数字索引的数组并假定数字索引从 0 开始
each — 返回数组中当前的键/值对并将数组指针向前移动一步
array each ( array &array )
返回 array 数组中当前指针位置的键/值对并向前移动数组指针。键值对被返回为四个单元的数组,键名为 0,1,key 和 value。单元 0 和 key 包含有数组单元的键名,1 和 value 包含有数据。
each() 经常和 list() 结合使用来遍历数组,例如:
<?php
$fruit = array(‘a’ => ‘apple’, ‘b’ => ‘banana’, ‘c’ => ‘cranberry’);
reset($fruit);
while (list($key, $val) = each($fruit)) {
echo “$key => $val\n”;
}
?>
近期评论