BLOG重新开放.
SORRY, 最近太忙太忙, 心思也比较倦怠, 最大的喜事是我儿子于2010.1.10顺利诞生了, 一切平安.
博客评论功能已经重新开放了, 欢迎大家评论.
另外我的服务器挺快的, 但是运行wordpress我自己很明显的感觉到打开wordpress的速度太慢了, 受不了. 准备近期换BLOG系统, 我目前正在开发的PHP版本的SmallMVC框架即将完工, 稍后将会使用本框架重新开发一个BLOG系统代替目前的.
感谢大家支持.
SORRY, 最近太忙太忙, 心思也比较倦怠, 最大的喜事是我儿子于2010.1.10顺利诞生了, 一切平安.
博客评论功能已经重新开放了, 欢迎大家评论.
另外我的服务器挺快的, 但是运行wordpress我自己很明显的感觉到打开wordpress的速度太慢了, 受不了. 准备近期换BLOG系统, 我目前正在开发的PHP版本的SmallMVC框架即将完工, 稍后将会使用本框架重新开发一个BLOG系统代替目前的.
感谢大家支持.
/*utf8编码时截取等长中英文字串*/ //英文标点[.,\"\\?!:_'] <? function substr_utf8($string,$start,$length) { //by aiou $chars = $string; //echo $string[0].$string[1].$string[2]; $i=0; do{ if (preg_match ("/[0-9a-zA-Z]/", $chars[$i])){//纯英文 $m++; } else {$n++; }//非英文字节, $k = $n/3+$m/2; $l = $n/3+$m;//最终截取长度;$l = $n/3+$m*2? $i++; } while($k < $length); $str1 = mb_substr($string,$start,$l,'utf-8');//保证不会出现乱码 return $str1; }
原文:http://aiou.javaeye.com/blog/371094
PHP拾遗捡漏(一)
最近在看<PHP和MySQL WEB开发>第四版, 把一些基础知识又复习了一遍, 还是很有收获的.
边看边记录一些文字吧.
1. echo 输出字符串
双引号和单引号的区别
$foo = 'hello'; echo $foo.' world!<br />'; echo "$foo world!<br />"; echo '$foo world!<br />';
运行后, 可以看出第一第二两个语句是等价的, 而第三个语句则原样输出.
结论: 对于任何简单类型的变量, 都可以将变量写入到一个由双引号引起来的字符串中, 在双引号中, 变量名称将被变量值所代替.而在单引号中, 变量名称,或者任何其他文本都会不经修改而直接发送到浏览器端.
Heredoc字符串也是插补的, 就像双引号字符串.
2.正确理解标识符
PHP中, 标识符是区分大小写的, $foo和$Foo是不同的, 而函数名称则不区分大小写.
$foo = 'foo'; $Foo = 'Foo'; echo "$foo<br />"; echo "$Foo<br />"; echo bar()."<br />"; echo Bar()."<br />"; function bar() { echo 'bar'; }
3.引用
PHP中引用操作符&可以在关联赋值时使用. 通常, 在将一个变量的值赋给另外一个变量的时候, 将先产生原变量的一个副本, 然后再将它保存在内存的其它的一个地方.
例如
$a = 5; $b = $a; $a = 7; // 此时$a=7, 而$b仍然等于5
这两行代码首先将产生一个$a的副本, 然后再将它保存到$b中, 如果随后改变$a的值, $b的值不会有任何变化.
可以通过引用操作符&来避免产生$a的副本, 此时$a和$b都指向了内存中的相同地址.
$a = 5; $b = &$a; $a = 7; // 此时$a和$b都等于7
可以通过unset($a)来重置它们来改变所指向的地址, 重置并不会改变$b(7)的值.
4. “执行操作符, 它是一对反向单引号, PHP将试着将其间的命令当做服务器端的命令行来执行. 表达式的值就是命令的执行结果.
$out = `dir c:` // windows, Linux为 `ls -la` echo $out;
5. isset()和empty()
bool isset(mixed var)
该函数需要一个变量名称作为参数, 如果这个变量存在返回true,否则返回false. 也可以传递一个由逗号间隔的变量列表, 如果所有变量都被设置了. 返回true.
可以使用unset()来销毁一个变量.
函数empty()可以用来检测一个变量是否存在,以及它的值是否为空和非0, 相应的返回true和false.
简单的来说empty()比isset()多检测值的非空和非0状态.
6. range()可以使用range()函数自动创建一个按升序排列的数字数组.
// 例如以下的代码将创建一个1~10的数字数组 $numbers = range(1, 10); //range()函数具有一个可选的第三个参数, 这个参数允许设定值之间的步幅. 例如创建一个1~10之间的奇数数组 $odds = range(1, 10, 2); //range()函数也可以对字符进行操作, 如下 $letters = range('a', 'z');
7. 数组排序
使用sort()函数, sort()函数可以将数组按字母或数字升序进行排序
$products = array('Tires', 'Oil', 'Spark Plugs'); sort($products); $prices = array(100, 10, 4); sort($prices);
sort()函数的第二个参数是可选的, 这个可选参数可以传递SORT_REGULAR(默认值), SORT_NUMERIC或SORT_STRING, sort()函数是区分大小写的.
使用asort()和ksort()函数对关联数组排序
函数asort()根据数组的每个元素值进行排序.
函数ksort()根据数组的每个元素进行排序.
以上三个函数都使数组按升序排序, 它们每个都对应有一个反向排序的函数, 分别是rsort(), arsort(), krsort().
用户自定义排序usort()
usort()函数的参数分别是希望排序的数组和用户比较的函数的名称
// 这是一个普通的二维数组, 存储了3种产品的代码,说明和价格. $products = array(array('TLR', 'Tires', 100), array('OIL', 'Oil', 10), array('SPK', 'Spark Plugs', 4)); // 以下代码对订单数组中的第二列(说明)按字母进行排序 function compare($x, $y) { if ($x[1] == $y[1]) return 0; else if ($x[1] < $y[1]) return -1; else return 1; } usort($products, 'compare') // 同时实现反向排序 function reverse_compare($x, $y) { if ($x[1] == $y[1]) returnn 0; else if ($x[1] < $y[1]) return 1; else return -1; } usort($products, 'reverse_compare');
转载请注明出处: http://www.suiyuan.org
本来想自己写个具体的例子的, 但是太忙了, 又怕转头就忘了, 用的网上的代码.
应该明白的是PHP5中的异常处理和类是紧密结合在一起的, 在进行异常捕捉前对代码中可能出现的异常情况进行判断, 然后抛出异常.
<?php // PHP 5 require_once('cmd_php5/Command.php'); class CommandManagerException extends Exception{} class IllegalCommandException extends Exception{} class CommandManager { private $cmdDir = "cmd_php5"; function __construct() { if (!is_dir($this->cmdDir)) { throw new CommandManagerException("directory error: $this->cmdDir"); } } function getCommandObject($cmd) { $path = "{$this->cmdDir}/{$cmd}.php"; if (!file_exists($path)) { throw new IllegalCommandException("Cannot find $path"); } require_once $path; if (!class_exists($cmd)) { throw new IllegalCommandException("class $cmd does not exist"); } $class = new ReflectionClass($cmd); if (!$class->isSubclassOf(new ReflectionClass('Command'))) { throw new IllegalCommandException("$cmd is not a Command"); } return $class->newInstance(); } } ?>
当我们的类不能找到正确的command目录时,将抛出一个CommandManagerException异常;当在生成Command对象时产生错误,则getCommandObject()方法将抛出一个IllegalCommandException异常。注意存在多个可能导致抛出IllegalCommandException异常的原因(如未找到文件,或在文件中未找到正确的类)。我们将前两个例子结合起来并为IllegalCommandException提供整型的错误标识常量来代表不同类型的出错原因。
现在CommandManager类已经具备了处理这多种出错情况的能力,我们可以增加新的catch语句来匹配不同的错误类型。
代码后半段
<?php // PHP 5 try { $mgr = new CommandManager(); $cmd = $mgr->getCommandObject('realcommand'); $cmd->execute(); } catch (CommandManagerException $e) { die($e->getMessage()); } catch (IllegalCommandException $e) { error_log($e->getMessage()); print "attempting recovery\n"; // perhaps attempt to invoke a default command? } catch (Exception $e) { print "Unexpected exception\n"; die($e->getMessage()); } ?>
看了代码, 应该明白这里和c#直接try…catch不同的是多了个判断的过程. 为什么在C#中不需要, 很简单, C#底层中已经对这些代码进行封装过了.
来个c#打开串口的例子
try { if (comPort.IsOpen) comPort.Close(); comPort.BaudRate = int.Parse(_baudRate); comPort.DataBits = int.Parse(_dataBits); comPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), _stopBits); comPort.Parity = (Parity)Enum.Parse(typeof(Parity), _parity); comPort.PortName = _portName; comPort.Open(); if (this.IsBatch) DisplayData(MsgType.Normal, "当前模式:批量传输,正在接收数据..\n"); else DisplayData(MsgType.Normal, "当前模式:实时传输,正在接受数据..\n"); return true; } catch (Exception ex) { //DisplayData(MsgType.Error, ex.Message); FormUtility.Alert(ex.Message); return false; }
以前对PHP5的异常处理机制了解的不够透彻, 按照C#的方法直接去了才发现还是有不同的. 呵呵, 学习了.
PHP 函数set_error_handler()的用法
<?PHP function ErrorHandler($errno, $errmsg, $errfile, $errline) { if ($errno == E_USER_ERROR) { $msg = "<strong>Custom Error:</strong>$errmsg<br />\n"; $msg .= "File:$errfile<br />\n"; $msg .= "Line Number:$errline<br />\n"; } echo $msg; // 记录错误信息 error_log(date("[Y-m-d H:i:s]")." -[".$_SERVER['REQUEST_URI']."] :".$msg."\n", 3, 'log.txt'); // exit(); // 必要时必须终止脚本执行. } // set_error_handler()函数用于让用户自定义错误处理函数 // set_error_handler(error_function, error_type) // error_function 必须, 制定发生错误时运行的函数 // error_type 可选, 规定不同的错误级别提示的不同信息, 默认是"E_ALL" set_error_handler('ErrorHandler'); $foo = 2; if ($foo > 1) { // trigger_error()接收一个错误信息和一个常量作为参数, // 常量为E_USER_ERROR -> a fatal error // E_USER_WARNING -> a non-fatal error // E_USER_NOTICE -> a report that may not represent an error trigger_error("A custom error has been trigglered", E_USER_ERROR); } ?>
PHP 函数set_exception_handler()的用法
<?php function ExceptionHandler($e) { echo "<strong>Exception:</strong>".$e->getMessage(); echo "Stack Trace String:".$e->getTraceAsString(); } // set_exception_handler()函数用于让用户自定义异常处理函数 // set_exception_handler(exception_function) // 该函数需要抛出的exception对象最为参数 // 在这个异常处理程序被执行后, 脚本会停止执行 set_exception_handler('ExceptionHandler'); throw new Exception('Uncaught Exception occurred'); ?>
Smarty, PHP的一个非常出名的模板引擎, 很少用, 最近用了一点, 记录一些心得以备日后查阅.
1. 使用Smarty进行循环嵌套
// 在这里定义$sec1为一个二维数组 $sec1 = $db->fetchAll("select * from category"); for($i=0; $i<count($sec1); $i++) { $sec1[$i]['news'] = $db->fetchAll("select * from news where cid = ".$sec1[$i]['id']." order by id desc limit 0, 5"); } $smarty->assign('sec1', $sec1); $smarty->left_delimiter = "<{"; $smarty->right_delimiter = "}>"; $smarty->display('news.html');
// 模版文件
<{section name=sec1 loop=$sec1}> <div class="inner"> <h1><a href="/category/<{$sec1[sec1].id}>.html"><{$sec1[sec1].name}></a></h1> <ul> <{section name=sec2 loop=$sec1[sec1].news}> <li> <a href="/news/<{$sec1[sec1].news[sec2].id}>.html" target="_blank"> <{$sec1[sec1].news[sec2].title}> </a> </li> <{/section}> </ul> </div> <{/section}>
2. Smarty对于类似分页情况时的多参数缓存
我们都知道可以通过$smarty->display(’NewsList.tpl’, $page)这样来实现类似与NewsList.php?page=1这样URL结构相同的情况缓存. 但是如果情况是NewsList.php?cid=1&Page=1这样呢? 或许大家也知道, 但是我今天在网上查阅了一下才知道原来这么简单,$smarty->display(’NewsList.tpl’, “cid:{$cid}-page:{$page}”)就可以了. 呵呵
Recent Comments