向东(L)xiangdong.org 说:
姜宇:框架这个东西,从设计到使用,都需要相对较高的软件工程功底,也意味着更高的学习
成本……君不见java和.net的框架搞得红红火火,惨不忍睹的程序照样比比皆是。
至于ZF那玩意,呃…就个人而言,我到目前为止,仍然只承认那是一个极富有智慧的代
码包…
另外还有一个,在我个人认知里,框架与PHP的本身特性是存在一点抵触的,这个极点
是效率。所以,针对大型系统就来批评框架,貌似有些以偏概全。
向东(L)xiangdong.org 说:
:D牛不?
加密助手 说:
--- 系统提示: 以下会话未被加密 ---
王哲宾 说:
说得有道理
向东(L)xiangdong.org 说:
ZF那玩意,呃…就个人而言,我到目前为止,仍然只承认那是一个极富有智慧的代
码包
王哲宾 说:
他在哪写得?
向东(L)xiangdong.org 说:
他给我发的邮件。
王哲宾 说:
php确实是不适合于使用重量级的框架
向东(L)xiangdong.org 说:
层次清就OK,我觉得。。
王哲宾 说:
它的执行方式决定了它的这个特点
向东(L)xiangdong.org 说:
执行方式?什么方式
王哲宾 说:
php每一个脚本先全部载入所有资源,执行完毕后全部放弃,所以使用太重的框架,会极耗内存和计算资源
王哲宾 说:
也就是形成调用栈太深的现象
向东(L)xiangdong.org 说:
呵呵,就是经常出站入站。JAVA为何能?
王哲宾 说:
轻量框架和简单的分层还是一定要采用的。
王哲宾 说:
java的执行方式不一样,对于内存管理也不一样,有很多都是一次装入,之道jvm重启才被释放的
王哲宾 说:
完全不一样的执行原理
向东(L)xiangdong.org 说:
嗯,那样做为何还效率低下?
王哲宾 说:
java?
向东(L)xiangdong.org 说:
对呀。
王哲宾 说:
解析速度的问题
向东(L)xiangdong.org 说:
放内存了嘛。。
王哲宾 说:
另外,很多东西需要调入内存
王哲宾 说:
事务性,安全性等等很多基础性的服务,需要预先装入
王哲宾 说:
象php太简单了,压根不考虑这些
向东(L)xiangdong.org 说:
为此它也就快于Java的原因?就是一个简单。
王哲宾 说:
差不多
王哲宾 说:
啥都不考虑,能不快?
向东(L)xiangdong.org 说:
呵呵,也是,PHP 要是做得像java我想它也会慢上来的。
王哲宾 说:
象c也是全都不考虑,比php还快
王哲宾 说:
呵呵
王哲宾 说:
那当然
王哲宾 说:
出发点就不一样
王哲宾 说:
java是基于工业级应用产生的,php只是个人网站开发才出现的
王哲宾 说:
能一样吗
向东(L)xiangdong.org 说:
呵呵,也是。。java
定位和出生就不凡
向东(L)xiangdong.org 说:
我在想搞4年PHP后搞嘛去。。
哈哈。。。
向东(L)xiangdong.org 说:
先搞着,我昨天买了本Linux 下的c++,最近在学gtk.
姜宇:框架这个东西,从设计到使用,都需要相对较高的软件工程功底,也意味着更高的学习
成本……君不见java和.net的框架搞得红红火火,惨不忍睹的程序照样比比皆是。
至于ZF那玩意,呃…就个人而言,我到目前为止,仍然只承认那是一个极富有智慧的代
码包…
另外还有一个,在我个人认知里,框架与PHP的本身特性是存在一点抵触的,这个极点
是效率。所以,针对大型系统就来批评框架,貌似有些以偏概全。
向东(L)xiangdong.org 说:
:D牛不?
加密助手 说:
--- 系统提示: 以下会话未被加密 ---
王哲宾 说:
说得有道理
向东(L)xiangdong.org 说:
ZF那玩意,呃…就个人而言,我到目前为止,仍然只承认那是一个极富有智慧的代
码包
王哲宾 说:
他在哪写得?
向东(L)xiangdong.org 说:
他给我发的邮件。
王哲宾 说:
php确实是不适合于使用重量级的框架
向东(L)xiangdong.org 说:
层次清就OK,我觉得。。
王哲宾 说:
它的执行方式决定了它的这个特点
向东(L)xiangdong.org 说:
执行方式?什么方式
王哲宾 说:
php每一个脚本先全部载入所有资源,执行完毕后全部放弃,所以使用太重的框架,会极耗内存和计算资源
王哲宾 说:
也就是形成调用栈太深的现象
向东(L)xiangdong.org 说:
呵呵,就是经常出站入站。JAVA为何能?
王哲宾 说:
轻量框架和简单的分层还是一定要采用的。
王哲宾 说:
java的执行方式不一样,对于内存管理也不一样,有很多都是一次装入,之道jvm重启才被释放的
王哲宾 说:
完全不一样的执行原理
向东(L)xiangdong.org 说:
嗯,那样做为何还效率低下?
王哲宾 说:
java?
向东(L)xiangdong.org 说:
对呀。
王哲宾 说:
解析速度的问题
向东(L)xiangdong.org 说:
放内存了嘛。。
王哲宾 说:
另外,很多东西需要调入内存
王哲宾 说:
事务性,安全性等等很多基础性的服务,需要预先装入
王哲宾 说:
象php太简单了,压根不考虑这些
向东(L)xiangdong.org 说:
为此它也就快于Java的原因?就是一个简单。
王哲宾 说:
差不多
王哲宾 说:
啥都不考虑,能不快?
向东(L)xiangdong.org 说:
呵呵,也是,PHP 要是做得像java我想它也会慢上来的。
王哲宾 说:
象c也是全都不考虑,比php还快
王哲宾 说:
呵呵
王哲宾 说:
那当然
王哲宾 说:
出发点就不一样
王哲宾 说:
java是基于工业级应用产生的,php只是个人网站开发才出现的
王哲宾 说:
能一样吗
向东(L)xiangdong.org 说:
呵呵,也是。。java
定位和出生就不凡
向东(L)xiangdong.org 说:
我在想搞4年PHP后搞嘛去。。
哈哈。。。
向东(L)xiangdong.org 说:
先搞着,我昨天买了本Linux 下的c++,最近在学gtk.
profiling 基础
http://www.xaprb.com/blog/2006/10/12/how-to-profile-a-query-in-mysql/
http://www.xaprb.com/blog/2006/10/15/a-case-study-in-profiling-queries-in-mysql/
http://www.xaprb.com/blog/2006/10/17/mysql-profiling-case-study-part-2/
profiling 进阶
http://www.mysqlperformanceblog.com/2009/01/19/profiling-mysql-stored-routines/
http://www.mysqlperformanceblog.com/2008/05/18/wanted-better-memory-profiling-for-mysql/
maatkit--perldoc mk-query-profiler
profiling高级
http://dev.mysql.com/tech-resources/articles/pro-mysql-ch6.html
http://dev.mysql.com/tech-resources/articles/using-new-query-profiler.html
profiling骨灰级
http://www.scribd.com/doc/2669413/DTrace-and-MySQL-Presentation
http://forge.mysql.com/wiki/Using_DTrace_with_MySQL
http://wikis.sun.com/display/BluePrints/Optimizing+MySQL+Database+Application+Performance+with+Solaris+Dynamic+Tracing
http://www.xaprb.com/blog/2006/10/12/how-to-profile-a-query-in-mysql/
http://www.xaprb.com/blog/2006/10/15/a-case-study-in-profiling-queries-in-mysql/
http://www.xaprb.com/blog/2006/10/17/mysql-profiling-case-study-part-2/
profiling 进阶
http://www.mysqlperformanceblog.com/2009/01/19/profiling-mysql-stored-routines/
http://www.mysqlperformanceblog.com/2008/05/18/wanted-better-memory-profiling-for-mysql/
maatkit--perldoc mk-query-profiler
profiling高级
http://dev.mysql.com/tech-resources/articles/pro-mysql-ch6.html
http://dev.mysql.com/tech-resources/articles/using-new-query-profiler.html
profiling骨灰级
http://www.scribd.com/doc/2669413/DTrace-and-MySQL-Presentation
http://forge.mysql.com/wiki/Using_DTrace_with_MySQL
http://wikis.sun.com/display/BluePrints/Optimizing+MySQL+Database+Application+Performance+with+Solaris+Dynamic+Tracing
第一步,模拟登录界面,向https://reg.163.com/logins.jsp发送请求
注意curl函数一定要设置cookie的目录,以便日后读取.
可以这样设置curl_setopt( $ch, CURLOPT_COOKIEJAR, COOKIEJAR );
COOKIEJAR为自己定义的保存COOKIE的常量, 注意这个文件一定要可写
第二步, 获取cookie,向http://fm163.163.com/coremail/fc ... ifycookie=1&lightweight=1发送请求
curl_setopt( $ch, CURLOPT_COOKIEFILE, COOKIEJAR );
curl_setopt( $ch, CURLOPT_COOKIEJAR, COOKIEJAR );
这两块设置很关键
第三步,读取cookie
文件读写,从 COOKIEJAR 中读取.
获取cookieid.
第四步,发送请求http://g1a126.mail.163.com/a/s?sid=".$cookieid."&func=global:sequential
curl_setopt( $ch, CURLOPT_HTTPHEADER, array( "Content-Type: application/xml" ) );
$str = "user:getSignatures pab:getAllGroups ";
xml为发送请求的串.
注意curl函数一定要设置cookie的目录,以便日后读取.
可以这样设置curl_setopt( $ch, CURLOPT_COOKIEJAR, COOKIEJAR );
COOKIEJAR为自己定义的保存COOKIE的常量, 注意这个文件一定要可写
第二步, 获取cookie,向http://fm163.163.com/coremail/fc ... ifycookie=1&lightweight=1发送请求
curl_setopt( $ch, CURLOPT_COOKIEFILE, COOKIEJAR );
curl_setopt( $ch, CURLOPT_COOKIEJAR, COOKIEJAR );
这两块设置很关键
第三步,读取cookie
文件读写,从 COOKIEJAR 中读取.
获取cookieid.
第四步,发送请求http://g1a126.mail.163.com/a/s?sid=".$cookieid."&func=global:sequential
curl_setopt( $ch, CURLOPT_HTTPHEADER, array( "Content-Type: application/xml" ) );
$str = "
xml为发送请求的串.
config.php
url拼合代码:
define('BLOGBINDURL',"http://in-o.xianguo.com/sina/blogbind?email=%s&puid=%s&blogurl=%s&action=%s&apikey=%s&time=%s&securitykey=%s"); //测试
url拼合代码:
/**
* 绑定博客
*
* @param string $email 用户邮箱
* @param int $uid 用户uid
* @param string $blogurl 博客url
* @param int $action 操作类型 0 绑定 1 删除
* @return boolean
* 0:失败/1:成功
*/
public function bindblog($email,$uid,$blogurl,$action)
{
$time = time();
$securitykey = md5($uid . BIND_BLOG_APIKEY . $time . BIND_BLOG_PRIKEY);
$url = sprintf(BLOGBINDURL, urlencode($email), urlencode($uid), urlencode($blogurl), urlencode($action), urlencode($apikey), urlencode($time), urlencode($securitykey));
$flag = Check::request($url,$result);
if(1 == $flag) {
$resultReturn = json_decode($result,True);
if(0 === $resultReturn['status'])
return 1;
if(1 === $resultReturn['status'])
return 0;
} else {
return 0;
}
}
* 绑定博客
*
* @param string $email 用户邮箱
* @param int $uid 用户uid
* @param string $blogurl 博客url
* @param int $action 操作类型 0 绑定 1 删除
* @return boolean
* 0:失败/1:成功
*/
public function bindblog($email,$uid,$blogurl,$action)
{
$time = time();
$securitykey = md5($uid . BIND_BLOG_APIKEY . $time . BIND_BLOG_PRIKEY);
$url = sprintf(BLOGBINDURL, urlencode($email), urlencode($uid), urlencode($blogurl), urlencode($action), urlencode($apikey), urlencode($time), urlencode($securitykey));
$flag = Check::request($url,$result);
if(1 == $flag) {
$resultReturn = json_decode($result,True);
if(0 === $resultReturn['status'])
return 1;
if(1 === $resultReturn['status'])
return 0;
} else {
return 0;
}
}
首先我们看一下php手册中关于删除cookie的说明
------以下引用php手册内容--------------
要删除 cookie 需要确保它的失效期是在过去,才能触发浏览器的删除机制。
下面的例子说明了如何删除刚才设置的 cookie: 例子 2. setcookie() 删除
例子
// 将过期时间设为一小时前
删除一个cookie的方法就是把这个cookie的有效期设置为当前时间以前,这
也是几乎所有php程序员都会这么做。
后来一个初接触php的朋友告诉我,他在程序中本想把一个cookie的值设置为
空,结果导致这个cookie直接被删除。我当时的第一反应是不相信,于是测试
了一下
空.于是用winsock抓包,观察返回的http头,发现http头竟然是
这说明setcookie("testcookie", '');的的确确是将testcookie这个cookie直
接删除.而关于这种情况在php手册中完全没有说明.
最后阅读php源码,终于发现真相(这就是开源的好处了,有什么不清楚的内幕
直接查源码)
以下代码可以在php5.20的linux源码包中ext/standard/head.c第99行附近找到.
源码中清清楚楚的显示,if (value && value_len == 0) ,当value_len为0
时
sprintf(cookie, "Set-Cookie: %s=deleted; expires=%s", name, dt);
会发送删除cookie的http头给浏览器.
最后我们可以得出结论,在php中使用
setcookie($cookiename, '');或者 setcookie($cookiename, NULL);
都会删除cookie,当然这些手册中并没有。
------以下引用php手册内容--------------
bool setcookie ( string name [, string value [, int expire [, string path [, string domain [, bool secure]]]]] )
要删除 cookie 需要确保它的失效期是在过去,才能触发浏览器的删除机制。
下面的例子说明了如何删除刚才设置的 cookie: 例子 2. setcookie() 删除
例子
// 将过期时间设为一小时前
setcookie("TestCookie", "", time() - 3600);
setcookie("TestCookie", "", time() - 3600, "/~rasmus/", ".utoronto.ca", 1);
----------------引用结束--------------------------setcookie("TestCookie", "", time() - 3600, "/~rasmus/", ".utoronto.ca", 1);
删除一个cookie的方法就是把这个cookie的有效期设置为当前时间以前,这
也是几乎所有php程序员都会这么做。
后来一个初接触php的朋友告诉我,他在程序中本想把一个cookie的值设置为
空,结果导致这个cookie直接被删除。我当时的第一反应是不相信,于是测试
了一下
setcookie("testcookie", '');
print_r($_COOKIE);
结果果然是整个$_COOKIE数组都是空的,而非仅仅$_COOKIE['testcookie']为print_r($_COOKIE);
空.于是用winsock抓包,观察返回的http头,发现http头竟然是
Set-Cookie: testcookie=deleted; expires=Mon, 18-Jun-2007 02:42:33 GMT
这说明setcookie("testcookie", '');的的确确是将testcookie这个cookie直
接删除.而关于这种情况在php手册中完全没有说明.
最后阅读php源码,终于发现真相(这就是开源的好处了,有什么不清楚的内幕
直接查源码)
以下代码可以在php5.20的linux源码包中ext/standard/head.c第99行附近找到.
if (value && value_len == 0) {
/*
* MSIE doesn't delete a cookie when you set it to a null value
* so in order to force cookies to be deleted, even on MSIE, we
* pick an expiry date 1 year and 1 second in the past
*/
time_t t = time(NULL) - 31536001;
dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, t, 0 TSRMLS_CC);
sprintf(cookie, "Set-Cookie: %s=deleted; expires=%s", name, dt);
efree(dt);
} else {
sprintf(cookie, "Set-Cookie: %s=%s", name, value ? encoded_value : "");
if (expires > 0) {
strcat(cookie, "; expires=");
dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC);
strcat(cookie, dt);
efree(dt);
}
}
/*
* MSIE doesn't delete a cookie when you set it to a null value
* so in order to force cookies to be deleted, even on MSIE, we
* pick an expiry date 1 year and 1 second in the past
*/
time_t t = time(NULL) - 31536001;
dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, t, 0 TSRMLS_CC);
sprintf(cookie, "Set-Cookie: %s=deleted; expires=%s", name, dt);
efree(dt);
} else {
sprintf(cookie, "Set-Cookie: %s=%s", name, value ? encoded_value : "");
if (expires > 0) {
strcat(cookie, "; expires=");
dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC);
strcat(cookie, dt);
efree(dt);
}
}
源码中清清楚楚的显示,if (value && value_len == 0) ,当value_len为0
时
sprintf(cookie, "Set-Cookie: %s=deleted; expires=%s", name, dt);
会发送删除cookie的http头给浏览器.
最后我们可以得出结论,在php中使用
setcookie($cookiename, '');或者 setcookie($cookiename, NULL);
都会删除cookie,当然这些手册中并没有。
做ROR有一年了, 感觉非常好.配合敏捷实践(除了pair, 由于是和美国工程师远程合作.)开发速度的确快.一共三个人写代码,短短半年, 项目就基本结束了....
现在新项目即将到来, 客户在php和rails之间难以取舍. 我也打算趁此机会了解一下php.
由于项目定制性还是比较高,想通过成熟的CMS等系统来改改估计是没戏。
从头开发又觉得太慢。于是想从开源框架入手。
经过了解才发现, php新兴的一些框架基本上清一色的学习(或者叫抄袭,特别是cakePHP, 那简直抄得太厉害了.)rails。而且这些框架还发展的很好,越来越受到php社区的欢迎。 比如国外cakePHP,国内的Fleaphp, QeePHP等等,就不一一列举了.
昨天用cakePHP做了个简单的demo, 确实抄rails那是抄的相当直白。 甚至连rake都还有相应的东西代替。除了migration和filter我没找到对应的东西。让我一个不懂php的人,都还是可以很快地上手了.
一方面感叹php抄rails这种彻底,另一方面也感叹这些抄袭之作的确也带来了php开发效率的提升。虽然由于php本身的原因,框架的引入对性能的影响是比较大的。但是这些框架的出现大有重整php社区的意思。(至少客户就告诉我们,用rails不如用cakePHP,这样他们也不会引入更多风险。他们还介绍他们美国几个团队都又从rails转回cakePHP了.)
我就纳闷儿了,当时还觉得rails就是冲着php的市场去的。。。现在反而觉得rails的思想拯救了php...
大家觉得是应该继续说服客户呢? 还是就用山寨rails了呢?
PHP和Python/Ruby的运行机制有一个本质区别:PHP是每次HTTP请求过来以后,初始化全部资源(例如创建数据库链接、加载系统类库,创建缓存等等),处理完毕,释放全部资源,这不像Python/Ruby之类带有GC的脚本语言,Python/Ruby是初次启动的时候初始化资源,随后的请求就不必再次初始化资源了。
这种机制的差异带来的区别就是:
1、PHP极难出现严重的内存泄露问题,随便你代码写的多烂,反正每个请求一执行完毕,所有资源统统释放光。而Python/Ruby则需要依赖GC来回收内存,因此稍有不慎,还是会出现GC无法释放的内存泄露问题。
2、PHP每次请求都要初始化资源,这个开销非常大。所以尽管PHP解析器本身的运行速度是极快的,但是一旦使用复杂的PHP框架,那么由于需要每次请求的时候初始化整个框架,性能的下降非常厉害,你用一个很复杂的PHP框架的结果就是整体性能被Ruby远远甩开。这也是为什么PHP社区这么多年来,并不怎么倾向于使用框架的原因之一。
3、由于PHP这种每请求初始化资源的机制,也造成了PHP添加跨请求的高级特性相当困难,这是PHP本身一个很大的限制,但是反过来说,正是这种限制使得PHP始终保持在一个比较简单的web语言上面,而正是这一点才是PHP得以成为互联网第一Web编程语言的原因,因此也未必就不好。
总之,PHP和Ruby的差异还是很大的,不适合放在一起比较,其实应该比较的是Ruby和Python才对。
所以我觉得Rails这种框架性做法被PHP跟风以后,其实是把PHP带上了邪路,所以不如说是Rails在误导PHP的发展。顺便多说一句:DHH在编写basecamp之前,一直是用PHP的,并且自己还写了一个PHP的快速开发框架,他改用ruby以后,把当初自己写的PHP框架也移植过来了,这个框架实际上是Rails最初的原型。那么为什么DHH当初不直接基于PHP做Rails呢?非要改用ruby以后,才发表rails呢?你看看PHP这种运行机制就知道了,PHP做复杂的web开发框架并不是一条光明的道路。
PHP做复杂框架肯定是一个慢。
但做前端处理简直是简单,随意这么整都行,非常适用于容易变化的前端开发。而后端可以用各种高级的东西。
貌似很多高访问量的大网站就是这么搞的。
可以考虑一下 symfony php framework,有一些自己的特点, cakephp 太模仿 rails 了。
现在新项目即将到来, 客户在php和rails之间难以取舍. 我也打算趁此机会了解一下php.
由于项目定制性还是比较高,想通过成熟的CMS等系统来改改估计是没戏。
从头开发又觉得太慢。于是想从开源框架入手。
经过了解才发现, php新兴的一些框架基本上清一色的学习(或者叫抄袭,特别是cakePHP, 那简直抄得太厉害了.)rails。而且这些框架还发展的很好,越来越受到php社区的欢迎。 比如国外cakePHP,国内的Fleaphp, QeePHP等等,就不一一列举了.
昨天用cakePHP做了个简单的demo, 确实抄rails那是抄的相当直白。 甚至连rake都还有相应的东西代替。除了migration和filter我没找到对应的东西。让我一个不懂php的人,都还是可以很快地上手了.
一方面感叹php抄rails这种彻底,另一方面也感叹这些抄袭之作的确也带来了php开发效率的提升。虽然由于php本身的原因,框架的引入对性能的影响是比较大的。但是这些框架的出现大有重整php社区的意思。(至少客户就告诉我们,用rails不如用cakePHP,这样他们也不会引入更多风险。他们还介绍他们美国几个团队都又从rails转回cakePHP了.)
我就纳闷儿了,当时还觉得rails就是冲着php的市场去的。。。现在反而觉得rails的思想拯救了php...
大家觉得是应该继续说服客户呢? 还是就用山寨rails了呢?
PHP和Python/Ruby的运行机制有一个本质区别:PHP是每次HTTP请求过来以后,初始化全部资源(例如创建数据库链接、加载系统类库,创建缓存等等),处理完毕,释放全部资源,这不像Python/Ruby之类带有GC的脚本语言,Python/Ruby是初次启动的时候初始化资源,随后的请求就不必再次初始化资源了。
这种机制的差异带来的区别就是:
1、PHP极难出现严重的内存泄露问题,随便你代码写的多烂,反正每个请求一执行完毕,所有资源统统释放光。而Python/Ruby则需要依赖GC来回收内存,因此稍有不慎,还是会出现GC无法释放的内存泄露问题。
2、PHP每次请求都要初始化资源,这个开销非常大。所以尽管PHP解析器本身的运行速度是极快的,但是一旦使用复杂的PHP框架,那么由于需要每次请求的时候初始化整个框架,性能的下降非常厉害,你用一个很复杂的PHP框架的结果就是整体性能被Ruby远远甩开。这也是为什么PHP社区这么多年来,并不怎么倾向于使用框架的原因之一。
3、由于PHP这种每请求初始化资源的机制,也造成了PHP添加跨请求的高级特性相当困难,这是PHP本身一个很大的限制,但是反过来说,正是这种限制使得PHP始终保持在一个比较简单的web语言上面,而正是这一点才是PHP得以成为互联网第一Web编程语言的原因,因此也未必就不好。
总之,PHP和Ruby的差异还是很大的,不适合放在一起比较,其实应该比较的是Ruby和Python才对。
所以我觉得Rails这种框架性做法被PHP跟风以后,其实是把PHP带上了邪路,所以不如说是Rails在误导PHP的发展。顺便多说一句:DHH在编写basecamp之前,一直是用PHP的,并且自己还写了一个PHP的快速开发框架,他改用ruby以后,把当初自己写的PHP框架也移植过来了,这个框架实际上是Rails最初的原型。那么为什么DHH当初不直接基于PHP做Rails呢?非要改用ruby以后,才发表rails呢?你看看PHP这种运行机制就知道了,PHP做复杂的web开发框架并不是一条光明的道路。
PHP做复杂框架肯定是一个慢。
但做前端处理简直是简单,随意这么整都行,非常适用于容易变化的前端开发。而后端可以用各种高级的东西。
貌似很多高访问量的大网站就是这么搞的。
可以考虑一下 symfony php framework,有一些自己的特点, cakephp 太模仿 rails 了。
在中央民族大学光学毕业的我,回过头一看,我们学校还准备开设光学研究生,呵呵:
光学专业硕士研究生培养方案.doc
光学专业硕士研究生培养方案.doc
拷贝如下代码,保存为clean.bat,(后缀为bat),双击即可开始清理:
@echo off
echo 正在清除系统垃圾文件,请稍等......
del /f /s /q %systemdrive%\*.tmp
del /f /s /q %systemdrive%\*._mp
del /f /s /q %systemdrive%\*.log
del /f /s /q %systemdrive%\*.gid
del /f /s /q %systemdrive%\*.chk
del /f /s /q %systemdrive%\*.old
del /f /s /q %systemdrive%\recycled\*.*
del /f /s /q %windir%\*.bak
del /f /s /q %windir%\prefetch\*.*
rd /s /q %windir%\temp & md %windir%\temp
del /f /q %userprofile%\cookies\*.*
del /f /q %userprofile%\recent\*.*
del /f /s /q "%userprofile%\Local Settings\Temporary Internet Files\*.*"
del /f /s /q "%userprofile%\Local Settings\Temp\*.*"
del /f /s /q "%userprofile%\recent\*.*"
echo 清除系统LJ完成!
echo. & pause
echo 正在清除系统垃圾文件,请稍等......
del /f /s /q %systemdrive%\*.tmp
del /f /s /q %systemdrive%\*._mp
del /f /s /q %systemdrive%\*.log
del /f /s /q %systemdrive%\*.gid
del /f /s /q %systemdrive%\*.chk
del /f /s /q %systemdrive%\*.old
del /f /s /q %systemdrive%\recycled\*.*
del /f /s /q %windir%\*.bak
del /f /s /q %windir%\prefetch\*.*
rd /s /q %windir%\temp & md %windir%\temp
del /f /q %userprofile%\cookies\*.*
del /f /q %userprofile%\recent\*.*
del /f /s /q "%userprofile%\Local Settings\Temporary Internet Files\*.*"
del /f /s /q "%userprofile%\Local Settings\Temp\*.*"
del /f /s /q "%userprofile%\recent\*.*"
echo 清除系统LJ完成!
echo. & pause
尽职尽责升级版本:躬身主动、一专多能、不等不靠、互相补台。
我们后方配备的先进设备、优质资源,应该在前线一发现目标和机会时就能及时发挥作用,提供有效的支持,而不是拥有资源的人来指挥战争、拥兵自重。谁来呼唤炮火,应该让听得见炮声的人来决策。
阅读全文
我们后方配备的先进设备、优质资源,应该在前线一发现目标和机会时就能及时发挥作用,提供有效的支持,而不是拥有资源的人来指挥战争、拥兵自重。谁来呼唤炮火,应该让听得见炮声的人来决策。
阅读全文
http://blog.chinaunix.net/u/29134/showart_1316574.html
1、慎重选择表名。
有两种选择:
按照多数开发语言的命名规则。比如(myCustomer)。
按照多数开源思想命名规则。比如(my_customer)。
按照咱们中国人的思想。比如(我的客户)。
第一种有个缺点,很容易忘掉大写的字母。
第二种则比较好,每个WORD间用下划线连接,避免遗忘。
第三种建议不要用,虽然很好记。不觉得解析这个表的时候还需要编码转化吗?我个人理解,大家可以补充。
2. 关于编码的设定。
A. GBK/GB2312.(适用于纯中文存储)。
B. UTF8.(适用于中英文混合存储)。
C. LATIN1。(适用于纯英文存储)。
D. 其他的。
3. 关于表引擎的选择。
A. MYISAM.(很多人说她的表级锁定会带来好多问题,其实只要设计好对应的表以及写好对应的SQL查询就没有那么大的问题。)
B. INNODB. (如果要用到事务,选择她不会错。至于多数人讲的MASTER/SLAVE结构上用INNODB在MASTER的选择是否正确,就要看你怎么用了。不能一味的疯狂使用INNODB。除非你想要确保非常高可用性,
)
C. CSV. (以前我写过文章,关于这个引擎。个人觉得最主要的是来存储少量数据以及从EXCEL到MYSQL的转换方面会很有用。当然只要涉及到规则数据的导入,她就可以办到。)
D. BLACKHOLE. (觉得最完美的用处在于MASETR/SLAVE上面,并且MASTER是一个临时的专门负责写的机器。不过缺点也很多,会与MYISAM或者INNODB或者其他的引擎有所冲突,这点自己要做个权衡)。
E. MEMORY. (应该说是MYISAM的兄弟了。不过在读内存总比读磁盘的速度要快。不过要注意,它不支持动态数据类型)。
F. FEDERATED. (典型的分布式引擎。我以前文章中有介绍。)
G. NDB。(网络版存储引擎。因为Replication 总是有延迟,所以如果系统容不得任何延迟,就用这个吧。)
H. FOLCON。(6.0后用来代替INNODB的引擎。)
I. 其他旧的以及新开发的引擎具体介绍:http://dev.mysql.com/doc/refman/6.0/en/storage-engines.html)。
4. 关于属性数据类型的选择。
A. INT(一个字节的TINYINT,两个字节的SMALLINT,三个字节的MEDIUMINT,四个字节的INT,8个字节的BIGINT。记住:UNSIGNED不管你定义或者不定义,都不影响内部的存储字节大小)
B. 少于10个字符用CHAR是在合适不过了。(不过要记住在MEMORY引擎里面会自动把VARCHAR转化为CHAR)
C. 我一般用DECIMAL或者NUMERIC来代替FLOAT 或者DOUBLE。因为老板要求精确的数字。如果不要求精确的,那就用FLOAT吧。速度快,占空间小。(DECIMA、FLOAT(P)是动态存储。比如:DECIMAL(10,2)占用5个字节。FLOAT占4个字节,)
D. BLOB,TEXT,VARCHAR(一般存放文章内容,特别是新闻网站。需要的字节数是所存储的字符长度+1。记住BLOB和VARCHAR是TEXT和CHAR的BINARY类型)
E. ENUM(在一定范围内绝佳的代替VARCHAR和CHAR的工具,因为她只占一到两个字节。)
F. 时间和日期类型(占3个字节的DATE,8个字节的DATETIME,4个字节的TIMESTAMP,3个字节的TIME,1个字节的YEAR。)。如果要存储比如‘1983’这样的年份,用YEAR明显比VARCHAR或者CHAR要节省空间。因为后者要占5个字节。
G. BOOLEAN(用来存储YES或者NO之类的值,占用一个字节。)
H. 关于自增字段。目前我们的项目中涉及到好多ORDER BY RAND()操作。此类语句在数据库并发大的时候会造成CPU严重阻塞,持续产生数据库死锁!解决此类问题最好的办法就是利用自增字段,用程序随即生成数字序列,或者在数据库端随即生成数字序列。
I. 关于ZEROFILL。非常好用的前置填补0的存储,而不是用用对应个数的空串来代替。在需要前置补零的操作中INT ZEROFILL可以用来代替CHAR或者VARCHR。
5. 关于默认值。
A. 在5.0之后,只要设定字段为NOT NULL,系统自动给出默认值。对应CHAR->’’,INT->0,BOOLEAN->0等等。
B. 在5.0之前的版本,需要手动指定默认值,否则会出现一定的异常。到时候查都不好查了。
6. 关于多数据库建立。
A. 应该把对应的业务放在各自不同的数据库里,而不是所有业务放到一个库里面。
B. 数据库的命名和表命名一样。
7. 关于索引。
A. 设计表初期尽量考虑到应该建立的索引。所有建立的索引一定要测试一下,看是否有必要,否则会翻倍的减少写数据的性能。
B. 对于只有存储0或者1的列,尽量干掉索引,单独分出两个表。一个代替0,另外一个代替1。或者在一个字段里面用EMUM或者CHAR(0)或者CHAR(1)来代替。
PS: 最后一个要值得注意的,就是尽量所有的字段用NOT NULL。虽然MYSQL可以对NULL列进行索引,不过我不建议。
1、慎重选择表名。
有两种选择:
按照多数开发语言的命名规则。比如(myCustomer)。
按照多数开源思想命名规则。比如(my_customer)。
按照咱们中国人的思想。比如(我的客户)。
第一种有个缺点,很容易忘掉大写的字母。
第二种则比较好,每个WORD间用下划线连接,避免遗忘。
第三种建议不要用,虽然很好记。不觉得解析这个表的时候还需要编码转化吗?我个人理解,大家可以补充。
2. 关于编码的设定。
A. GBK/GB2312.(适用于纯中文存储)。
B. UTF8.(适用于中英文混合存储)。
C. LATIN1。(适用于纯英文存储)。
D. 其他的。
3. 关于表引擎的选择。
A. MYISAM.(很多人说她的表级锁定会带来好多问题,其实只要设计好对应的表以及写好对应的SQL查询就没有那么大的问题。)
B. INNODB. (如果要用到事务,选择她不会错。至于多数人讲的MASTER/SLAVE结构上用INNODB在MASTER的选择是否正确,就要看你怎么用了。不能一味的疯狂使用INNODB。除非你想要确保非常高可用性,
)
C. CSV. (以前我写过文章,关于这个引擎。个人觉得最主要的是来存储少量数据以及从EXCEL到MYSQL的转换方面会很有用。当然只要涉及到规则数据的导入,她就可以办到。)
D. BLACKHOLE. (觉得最完美的用处在于MASETR/SLAVE上面,并且MASTER是一个临时的专门负责写的机器。不过缺点也很多,会与MYISAM或者INNODB或者其他的引擎有所冲突,这点自己要做个权衡)。
E. MEMORY. (应该说是MYISAM的兄弟了。不过在读内存总比读磁盘的速度要快。不过要注意,它不支持动态数据类型)。
F. FEDERATED. (典型的分布式引擎。我以前文章中有介绍。)
G. NDB。(网络版存储引擎。因为Replication 总是有延迟,所以如果系统容不得任何延迟,就用这个吧。)
H. FOLCON。(6.0后用来代替INNODB的引擎。)
I. 其他旧的以及新开发的引擎具体介绍:http://dev.mysql.com/doc/refman/6.0/en/storage-engines.html)。
4. 关于属性数据类型的选择。
A. INT(一个字节的TINYINT,两个字节的SMALLINT,三个字节的MEDIUMINT,四个字节的INT,8个字节的BIGINT。记住:UNSIGNED不管你定义或者不定义,都不影响内部的存储字节大小)
B. 少于10个字符用CHAR是在合适不过了。(不过要记住在MEMORY引擎里面会自动把VARCHAR转化为CHAR)
C. 我一般用DECIMAL或者NUMERIC来代替FLOAT 或者DOUBLE。因为老板要求精确的数字。如果不要求精确的,那就用FLOAT吧。速度快,占空间小。(DECIMA、FLOAT(P)是动态存储。比如:DECIMAL(10,2)占用5个字节。FLOAT占4个字节,)
D. BLOB,TEXT,VARCHAR(一般存放文章内容,特别是新闻网站。需要的字节数是所存储的字符长度+1。记住BLOB和VARCHAR是TEXT和CHAR的BINARY类型)
E. ENUM(在一定范围内绝佳的代替VARCHAR和CHAR的工具,因为她只占一到两个字节。)
F. 时间和日期类型(占3个字节的DATE,8个字节的DATETIME,4个字节的TIMESTAMP,3个字节的TIME,1个字节的YEAR。)。如果要存储比如‘1983’这样的年份,用YEAR明显比VARCHAR或者CHAR要节省空间。因为后者要占5个字节。
G. BOOLEAN(用来存储YES或者NO之类的值,占用一个字节。)
H. 关于自增字段。目前我们的项目中涉及到好多ORDER BY RAND()操作。此类语句在数据库并发大的时候会造成CPU严重阻塞,持续产生数据库死锁!解决此类问题最好的办法就是利用自增字段,用程序随即生成数字序列,或者在数据库端随即生成数字序列。
I. 关于ZEROFILL。非常好用的前置填补0的存储,而不是用用对应个数的空串来代替。在需要前置补零的操作中INT ZEROFILL可以用来代替CHAR或者VARCHR。
5. 关于默认值。
A. 在5.0之后,只要设定字段为NOT NULL,系统自动给出默认值。对应CHAR->’’,INT->0,BOOLEAN->0等等。
B. 在5.0之前的版本,需要手动指定默认值,否则会出现一定的异常。到时候查都不好查了。
6. 关于多数据库建立。
A. 应该把对应的业务放在各自不同的数据库里,而不是所有业务放到一个库里面。
B. 数据库的命名和表命名一样。
7. 关于索引。
A. 设计表初期尽量考虑到应该建立的索引。所有建立的索引一定要测试一下,看是否有必要,否则会翻倍的减少写数据的性能。
B. 对于只有存储0或者1的列,尽量干掉索引,单独分出两个表。一个代替0,另外一个代替1。或者在一个字段里面用EMUM或者CHAR(0)或者CHAR(1)来代替。
PS: 最后一个要值得注意的,就是尽量所有的字段用NOT NULL。虽然MYSQL可以对NULL列进行索引,不过我不建议。
SVN版本信息的删除:find . -type d -name “.svn”|xargs rm -rf或者find . -type d -iname “.svn” -exec rm -rf {} \;
<?php
$array_test = array("status"=>0,"desc"=>iconv("gbk","utf-8","成功"),"title"=>iconv("gbk","utf-8","我的博客"),"blogId"=>"100");//将中文的gbk转为utf-8,便于json_encode编码,否则中文为空:gbk的PHP文件必须转为utf-8的编码。
$result = json_encode($array_test);
print_r($result);
$json2array = json_decode($result,True);//True让它转为数组,这里特别注意!
$json2array['desc'] = iconv("utf-8","gbk",$json2array['desc']);//将utf-8---->gbk2312 浏览器用Charset:GBK2312显示才能正常
$json2array['title'] = iconv("utf-8","gbk",$json2array['title']);//同上
//去掉上面两行,浏览器在Utf-8下面显示中文正常,Charset:GBK2312下不正常,乱码!
print_r($json2array);
?>
$array_test = array("status"=>0,"desc"=>iconv("gbk","utf-8","成功"),"title"=>iconv("gbk","utf-8","我的博客"),"blogId"=>"100");//将中文的gbk转为utf-8,便于json_encode编码,否则中文为空:gbk的PHP文件必须转为utf-8的编码。
$result = json_encode($array_test);
print_r($result);
$json2array = json_decode($result,True);//True让它转为数组,这里特别注意!
$json2array['desc'] = iconv("utf-8","gbk",$json2array['desc']);//将utf-8---->gbk2312 浏览器用Charset:GBK2312显示才能正常
$json2array['title'] = iconv("utf-8","gbk",$json2array['title']);//同上
//去掉上面两行,浏览器在Utf-8下面显示中文正常,Charset:GBK2312下不正常,乱码!
print_r($json2array);
?>
字符转化的函数:
来自PHP高级编程QQ群:我姓--]苏
function zhjson($v){
if(is_array($v)){
foreach($v as $key =>$value){
$v[$key]=zhjson($value);
}
return $v;
}else{
return iconv("gb2312","utf-8",$v);
}
}
if(is_array($v)){
foreach($v as $key =>$value){
$v[$key]=zhjson($value);
}
return $v;
}else{
return iconv("gb2312","utf-8",$v);
}
}
让我想起我们自己的一个函数:(一样一样的)
function addslashes_array(&$ar)
{
if (is_array ( $ar ))
{
foreach ( $ar as $key => $ar_sub )
{
$this->addslashes_array ( $ar [$key] );
}
}
else if (is_string ( $ar ))
{
$ar = addslashes ( $ar );
}
}
{
if (is_array ( $ar ))
{
foreach ( $ar as $key => $ar_sub )
{
$this->addslashes_array ( $ar [$key] );
}
}
else if (is_string ( $ar ))
{
$ar = addslashes ( $ar );
}
}
这个方法也还不错:
膘叔(19129540) 15:27:14
来自PHP高级编程QQ群
乱码我更不搞了,我会直接在smarty模版里调用mb_string
<?php
function request($url,&$result,$timeout=10) {
$ctx = stream_context_create(array(
'http' => array(
'timeout' =>$timeout
)
));
$result = file_get_contents($url,false,$ctx);
if ($result === false) {
error_log("request $url timeout",0);
return 0;
}
return 1;
}
define('BLOGBINDURL',"http://in-o.xianguo.com/sina/blogbind?");
//define('BLOGBINDURL',"http://localhost/get.php?");
function bindblog($email,$uid,$blogurl,$action)
{
$apikey = '4810512c96ee6'; //用于身份检验
$time = time();
$privete_key = "xianguosinapass";
$securitykey = md5($uid.$apikey.$time.$privete_key);//securitykey = md5(puid+apikey+time+privete_key)
$encodeStr = "email=".urlencode($email)."&puid=".urlencode($uid)."&blogUrl=".urlencode($blogurl)."&action=".urlencode($action)."&apikey=".urlencode($apikey)."&time=".urlencode($time)."&securitykey=".urlencode($securitykey);
$url = BLOGBINDURL.$encodeStr;
$flag = request($url,$result);
if(1 == $flag)
{
$resultReturn = json_decode($result);
print_r($resultReturn);
if(0 == $resultReturn['status'])
return true;
if(1 == $resultReturn['status'])
return false;
}else
{
return false;
}
}
$email = "xdy***@126.com";
$uid = 1548940117;
$blogurl = "http://blog.sina.com.cn/warsharp";
$action = 0;
bindblog($email,$uid,$blogurl,$action);
?>
function request($url,&$result,$timeout=10) {
$ctx = stream_context_create(array(
'http' => array(
'timeout' =>$timeout
)
));
$result = file_get_contents($url,false,$ctx);
if ($result === false) {
error_log("request $url timeout",0);
return 0;
}
return 1;
}
define('BLOGBINDURL',"http://in-o.xianguo.com/sina/blogbind?");
//define('BLOGBINDURL',"http://localhost/get.php?");
function bindblog($email,$uid,$blogurl,$action)
{
$apikey = '4810512c96ee6'; //用于身份检验
$time = time();
$privete_key = "xianguosinapass";
$securitykey = md5($uid.$apikey.$time.$privete_key);//securitykey = md5(puid+apikey+time+privete_key)
$encodeStr = "email=".urlencode($email)."&puid=".urlencode($uid)."&blogUrl=".urlencode($blogurl)."&action=".urlencode($action)."&apikey=".urlencode($apikey)."&time=".urlencode($time)."&securitykey=".urlencode($securitykey);
$url = BLOGBINDURL.$encodeStr;
$flag = request($url,$result);
if(1 == $flag)
{
$resultReturn = json_decode($result);
print_r($resultReturn);
if(0 == $resultReturn['status'])
return true;
if(1 == $resultReturn['status'])
return false;
}else
{
return false;
}
}
$email = "xdy***@126.com";
$uid = 1548940117;
$blogurl = "http://blog.sina.com.cn/warsharp";
$action = 0;
bindblog($email,$uid,$blogurl,$action);
?>
同时在smarty中增加了这个函数的调用。可以通过模板调用。
增加的方法名是:truncate_cn
实例:{$title| truncate_cn :80:’ 'utf-8’:’…’}
默认情况下,省略字符为… ,如果不需要省略字符,最后一下用’’。
我建议模板中可以使用这种方法,提出如果在模板中添加增加编译负担,但是
smarty模板编译一次,永久使用(只要模板没有修改)。所以编译也不会造成多少损耗。
函数的原型如下:
有一个哥们写了个函数:
增加的方法名是:truncate_cn
实例:{$title| truncate_cn :80:’ 'utf-8’:’…’}
默认情况下,省略字符为… ,如果不需要省略字符,最后一下用’’。
我建议模板中可以使用这种方法,提出如果在模板中添加增加编译负担,但是
smarty模板编译一次,永久使用(只要模板没有修改)。所以编译也不会造成多少损耗。
函数的原型如下:
/**
* 中英文混杂字符串截取
*
* @param string $string
* 原字符串
* @param interger $length
* 截取的字符数
* @param string $etc
* 省略字符
* @param string $charset
* 原字符串的编码
*
* @return string
*/
function substr_cn($string, $length = 80, $charset = 'UTF-8', $etc = '...') {
if(mb_strwidth($string,'UTF-8')<$length) return $string;
return mb_strimwidth($string,0,$length,'',$charset) . $etc;
}
* 中英文混杂字符串截取
*
* @param string $string
* 原字符串
* @param interger $length
* 截取的字符数
* @param string $etc
* 省略字符
* @param string $charset
* 原字符串的编码
*
* @return string
*/
function substr_cn($string, $length = 80, $charset = 'UTF-8', $etc = '...') {
if(mb_strwidth($string,'UTF-8')<$length) return $string;
return mb_strimwidth($string,0,$length,'',$charset) . $etc;
}
有一个哥们写了个函数:
function msubstr($str, $start, $len) {
$tmpstr = "";
$strlen = $start + $len;
for($i = 0; $i < $strlen; $i++) {
if(ord(substr($str, $i, 1)) > 0xa0) {
$tmpstr .= substr($str, $i, 2);
$i++;
} else
$tmpstr .= substr($str, $i, 1);
}
return $tmpstr;
}
$tmpstr = "";
$strlen = $start + $len;
for($i = 0; $i < $strlen; $i++) {
if(ord(substr($str, $i, 1)) > 0xa0) {
$tmpstr .= substr($str, $i, 2);
$i++;
} else
$tmpstr .= substr($str, $i, 1);
}
return $tmpstr;
}
这是我作为一个初学者最简单的一个多进程程序。
编译后使用:
# ./a.out 11 22
the number 1 process overd
the number 2 process overd
the number 3 process overd
就是按你的输入分别启动多个进程,在data目录下创建多个文件,每个文件的内容是创建他的进程的PID。
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int
main(int argc,char *argv[])
{
int i,fd;
char buf[1024];
pid_t pid;
for(i=1;i<argc;i++)
{
if((pid = fork())<0)
printf("fork error:no=%d\n",i);
else if(pid == 0)
{//子进程
chdir("data");
fd = open(argv[i],O_CREAT|O_TRUNC|O_WRONLY,S_IRWXU|S_IRWXG|S_IRWXO);
sprintf(buf,"pid:%d\n",getpid());
write(fd,buf,strlen(buf));
break;
}
}
printf("the number %d process overd\n",i);
waitpid(pid,NULL);
exit(0);
}
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int
main(int argc,char *argv[])
{
int i,fd;
char buf[1024];
pid_t pid;
for(i=1;i<argc;i++)
{
if((pid = fork())<0)
printf("fork error:no=%d\n",i);
else if(pid == 0)
{//子进程
chdir("data");
fd = open(argv[i],O_CREAT|O_TRUNC|O_WRONLY,S_IRWXU|S_IRWXG|S_IRWXO);
sprintf(buf,"pid:%d\n",getpid());
write(fd,buf,strlen(buf));
break;
}
}
printf("the number %d process overd\n",i);
waitpid(pid,NULL);
exit(0);
}
编译后使用:
# ./a.out 11 22
the number 1 process overd
the number 2 process overd
the number 3 process overd
就是按你的输入分别启动多个进程,在data目录下创建多个文件,每个文件的内容是创建他的进程的PID。
一、smarty truncate 截取
從字符串開始處截取某長度的字符.默認是80個。
你也可以指定第二個參數作為追加在截取字符串後面的文本字串.該追加字串被計算在截取長度中。
默認情況下,smarty會截取到一個詞的末尾。
如果你想要精確的截取多少個字符,把第三個參數改為"true" 。
例 截取:
index.php:
index.tpl:
輸出結果:
在smarty模板中截取指定长度的字符串
在smarty模板中截取指定长度的字符串,可使用truncate这个插件.
用法:
{{$data.value|truncate:28:'...'}}
28个字节14个字数输出,多余部分输出...,一个汉字算两个.
参考中文截取的乱码问题:http://hi.baidu.com/pphu/blog/item/845c3a461663850b6a63e573.html
Smarty中文截取插件:http://hcmjf.bokee.com/viewdiary.204332042.html
二、smarty里嵌入PHP的截取实例:
從字符串開始處截取某長度的字符.默認是80個。
你也可以指定第二個參數作為追加在截取字符串後面的文本字串.該追加字串被計算在截取長度中。
默認情況下,smarty會截取到一個詞的末尾。
如果你想要精確的截取多少個字符,把第三個參數改為"true" 。
例 截取:
index.php:
$smarty = new Smarty;
$smarty->assign('articleTitle', 'Two Sisters Reunite after Eighteen Years at Checkout Counter.');
$smarty->display('index.tpl');
$smarty->assign('articleTitle', 'Two Sisters Reunite after Eighteen Years at Checkout Counter.');
$smarty->display('index.tpl');
index.tpl:
{$articleTitle}
{$articleTitle|truncate}
{$articleTitle|truncate:30}
{$articleTitle|truncate:30:""}
{$articleTitle|truncate:30:"---"}
{$articleTitle|truncate:30:"":true}
{$articleTitle|truncate:30:"...":true}
{$articleTitle|truncate}
{$articleTitle|truncate:30}
{$articleTitle|truncate:30:""}
{$articleTitle|truncate:30:"---"}
{$articleTitle|truncate:30:"":true}
{$articleTitle|truncate:30:"...":true}
輸出結果:
Two Sisters Reunite after Eighteen Years at Checkout Counter.
Two Sisters Reunite after Eighteen Years at Checkout Counter.
Two Sisters Reunite after...
Two Sisters Reunite after
Two Sisters Reunite after---
Two Sisters Reunite after Eigh
Two Sisters Reunite after E...
Two Sisters Reunite after Eighteen Years at Checkout Counter.
Two Sisters Reunite after...
Two Sisters Reunite after
Two Sisters Reunite after---
Two Sisters Reunite after Eigh
Two Sisters Reunite after E...
在smarty模板中截取指定长度的字符串
在smarty模板中截取指定长度的字符串,可使用truncate这个插件.
用法:
{{$data.value|truncate:28:'...'}}
28个字节14个字数输出,多余部分输出...,一个汉字算两个.
参考中文截取的乱码问题:http://hi.baidu.com/pphu/blog/item/845c3a461663850b6a63e573.html
Smarty中文截取插件:http://hcmjf.bokee.com/viewdiary.204332042.html
二、smarty里嵌入PHP的截取实例:
查看( 415 ) / 评论( 1 ) / 评分( 0 / 0 )
用iconv函数将gb2312转换为utf-8时,怎么有些汉字会出现问题,像"啰"字就会提示如下:
Notice: iconv() [function.iconv]: Detected an illegal character in input string
造成此错误的原因:
啰不是gb2312 字符集里的字,是gbk字符集里的字
iconv(gb2312,UTF-8//IGNORE,$要转的string);
这样就不会Notice: iconv() [function.iconv]:
iconv:
die(json_encode(array('code'=>-1,'msg'=>iconv('gbk','utf-8','没有相关IP'))));
die(json_encode(array('code'=>-1,'msg'=>iconv('gbk','utf8','没有相关IP'))));
必须要是:utf-8,得有中线,否则是会返回错误的,特别注意!
用iconv函数将gb2312转换为utf-8时,怎么有些汉字会出现问题,像"啰"字就会提示如下:
Notice: iconv() [function.iconv]: Detected an illegal character in input string
造成此错误的原因:
啰不是gb2312 字符集里的字,是gbk字符集里的字
iconv(gb2312,UTF-8//IGNORE,$要转的string);
这样就不会Notice: iconv() [function.iconv]:
iconv:
die(json_encode(array('code'=>-1,'msg'=>iconv('gbk','utf-8','没有相关IP'))));
die(json_encode(array('code'=>-1,'msg'=>iconv('gbk','utf8','没有相关IP'))));
必须要是:utf-8,得有中线,否则是会返回错误的,特别注意!





