手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表分类:PHP

通过file_get_contents来Post数据的实例

用file_get_contents来进行POST?很妖吧。
我也没有想到还有这种妖的东西。在向东的博客上看到这个的:http://www.xiangdong.org/blog/post/1623/

回忆未来?别惊讶,用他的话来说是山寨D。

原文:

file_get_contents.php: Post数据

PHP代码
  1. <?php  
  2. function Post($url$post = null)  
  3. {  
  4.     $context = array();  
  5.   
  6.     if (is_array($post))  
  7.     {  
  8.         ksort($post);  
  9.   
  10.         $context['http'] = array  
  11.         (  
  12.             'method' => 'POST',  
  13.             'content' => http_build_query($post'''&'),  
  14.         );  
  15.     }  
  16.   
  17.     return file_get_contents($url, false, stream_context_create($context));  
  18. }  
  19.   
  20. $data = array  
  21. (  
  22.     'name' => 'test',  
  23.     'email' => 'test@gmail.com',  
  24.     'submit' => 'submit',  
  25. );  
  26.   
  27. echo Post('http://localhost/5-5/request_post_result.php'$data);  
  28. ?>  
接收数据:

request_post_result.php  接收经过Post的数据:
PHP代码
  1. <?php  
  2. echo $_POST['name'];  
  3. echo $_POST['email'];  
  4. echo $_POST['submit'];  
  5. echo "fdfd";  
  6. ?>  


看一下,里面有一个特别的函数:stream_context_create,翻开手册看了一下,也没说什么呀,只是说:Creates and returns a stream context with any options supplied in options preset.

而file_get_contents呢?它说:

Note: Context support was added with PHP 5.0.0. For a description of contexts, refer to Reference CLX, Stream Functions.

关于Stream Functions,手册上这么描述的。。。

A wrapper is additional code which tells the stream how to handle specific protocols/encodings. For example, the http wrapper knows how to translate a URL into an HTTP/1.0 request for a file on a remote server. There are many wrappers built into PHP by default (See Appendix O), and additional, custom wrappers may be added either within a PHP script using stream_wrapper_register(), or directly from an extension using the API Reference in Chapter 52. Because any variety of wrapper may be added to PHP, there is no set limit on what can be done with them. To access the list of currently registered wrappers, use stream_get_wrappers().

A stream is referenced as: scheme://target

  • scheme(string) - The name of the wrapper to be used. Examples include: file, http, https, ftp, ftps, compress.zlib, compress.bz2, and php. See Appendix O for a list of PHP built-in wrappers. If no wrapper is specified, the function default is used (typically file://).

  • target - Depends on the wrapper used. For filesystem related streams this is typically a path and filename of the desired file. For network related streams this is typically a hostname, often with a path appended. Again, see Appendix O for a description of targets for built-in streams.

Tags: php, post

HeadFirst设计模式学习笔记(C#版):鸭子与策略(Strategy)模式

总是有一些奇怪的事情发生,我刚刚买了<HeadFirst 设计模式>,就有人写了如题的一篇文章。
我是用PHP的,而书上讲的例子是用伪代码(以java为蓝本)的,我也没有看多少呢,也没有想过要来实现一下,因为有些东西使用PHP的话,只会效率更低,解释型的,IO能节约还是要节约一下。
总想等看完再实现这些(第一大章还没有看完呢。)

不过,既然有人写了,总要宣扬一下的吧,代码虽然不一样,但思想总是一样的。
我也没有仔细看,就权当收藏吧。。

链接如下:

HeadFirst设计模式学习笔记(C#版):鸭子与策略(Strategy)模式

讲了什么呢?
摘要如下:


    策略模式的设计原则如下:
    1.   将应用中需要经常变化的代码独立出来,应和那些不需要经常变化的代码分开。
    2.   应针对接口,而不是类进行编程。
    3.  在类中应多用组合,少用继承。

    例子:

    我们要实现一个鸭子模拟器,这个鸭子模拟器由Duck类描述,而Duck类有如下4个行为:
    1.  display
    2.  swim
    3.  fly(飞)
    4.  quack(叫)

    其中swim是所有鸭子都具有的特性,而且所有鸭子的这些特性都相同,因此,这个方法可以直接在Duck类中实现。display方法也是所有鸭子具有的 特性,但随着鸭子的种类不同,display也有所不同,因此,display方法应为Duck类的抽象方法。fly和quack并不是所有鸭子的特性, 如橡皮鸭子即不会飞,也不会叫。因此,可以将这两个方法看作是两个行为,可将每一个行为设计成一个接口。这样可以和Duck类完全脱离。因为,fly和 quack与Duck一点关系都没有(别的东西也可能fly和quack),然后不同的fly和quack分别用实现相应接口的类表示。

Tags: headfirst, 模式, 策略模式, strategy

关于在线截图

 在线截图,对于PHP来说是有一点难度的,但也并非不可完成

从PHP5开始,为windows平台提供了两个现成的函数,但也只能在windows平台下使用,这两个函数其实还是使用了IE浏览器来进行截图,在使用这两个函数的时候,你可以明显看到IE会一闪而过。
 
不过在非windows平台下,就没有办法使用了。
为了实现这些功能,网上有很多例子哦,有使用mozilla核心的,有使用XXX核心的,但确实是没有一种完美的实现方案。
 
自己想想还有一种就是利用flash截图,然后生成图片的方案。这种的话就无所谓在哪个平台下面了吧?
 
网上有一些在线截图的:
http://www.wenwenba.com/
http://snapcasa.com
http://webthumb.bluga.net
http://flysky.fm1062.com/webSnapr/
但没有一款是PHP的。不过,正所谓事情都是人想出来的,我既然不能使用PHP截图,但是我可以利用这些网址截好图,用PHP抓回来嘛。。
黑黑

Tags: 截图, snapshot, webcatch

ZZ javaeye上的一篇翻译的访谈录:PHP创始人Rasmus Lerdorf 访谈

这是javaeye上的一篇访谈翻译(摘自程序员杂志),里面有一段关于PHP的安全性的话有点意思,用该页面下面的评论来说,搞的就象几个中国哥们在聊天一样。

我是觉得他们就象在一个group里的聊天记录。啥时候我也把QQ群或者MSN群里的聊天记录整理一下,也来个啥啥啥访谈。。。

原文地址:http://www.javaeye.com/news/4143-masters-listening-to-talk-4-php-founder-rasmus-lerdorf-interview-2

原文如下:

《程序员》杂志上连载的《PHP创始人访谈录》 的第二部分。


Chris DiBona : PHP 这个名字代表什么?

Rasmus Lerdorf : PHP是 , 恩 。 Hypertext Preprocessor , 这名字很蠢, 就是 PHP。  Zee v 与 Andi 是97年中加入进来的, 他们当时使用 php/fi, 在用到深度嵌套中碰到了一些问题, 他们都是计算机专业的, 知道如何写解析器 , 不像我是通过 hack 状态机这种方式来实现的 , 我想他们看到我程序的时候,一定对它竟然能工作感到惊奇吧 。

Chris DiBona : 呵呵,竟然可以工作

Rasmus Lerdorf : 他们是自愿做这些工作的, 当时我有点太累了,感觉自己像是在给半个因特网写程序, 人们不是给我发补丁来修补程序,而是。。。

Leo Laporte: 这是我的程序, 把 bug 给改了吧。

Rasmus Lerdorf : 是的 , 改了这个 Bug,  给我写个程序做这个。 我跟他们说做实现这个很容易,只要这么做, 他们说:“ 好吧,这是最麻烦的, 那剩下那些bug呢”

Chris DiBona :赶紧把 bug 修复了吧

Rasmus Lerdorf : 我当时的确很郁闷, 简直要把我掏空了。 当时感觉要么我就快要死了,否则我得把它移交到一个更大的 team 来做 。

Leo Laporte: 等等, 在我们继续谈论前,我觉得这是一个很有趣的话题, 这在开源社区并非罕见的情况吧。这种事情常常发生, 人们在说:“我管理不了这个社区了,我不干了,我简直要疯掉了”, chris 你肯定经历过很多这种情形, 这对于开源社区是不是个问题啊。

Chris DiBona : 是的,实际上我跟Rasmus探讨过这个问题, 每隔五个月,就有人公开在社区挑起这种事端, “天哪,开源项目完蛋了, 有人离开社区了”。 你知道的, 其实有人进入,有人离开这是很正常的。

Leo Laporte:事实上这事最近发生在 Zend Framework 社区了

Chris DiBona :是啊,让我们来谈谈吧,Rasmus

Rasmus Lerdorf : Zend Framework 是一个分离的项目,实话说,我也不是很清楚 ,你得问问他们,我也不清楚原因。

Chris DiBona : 从某一方面来说,实际上对大多数社区而言,某些人悄悄地离开了这也没有什么,尽管我不愿意这么说。

Leo Laporte: 对于用户而言,我们有时候的确不太满意所用的产品。

Rasmus Lerdorf :直到 php 3 ,实际上只有我一个人在做,当某人给我发了个 php 的补丁,我一定会重新写一遍,因为这是我的产品

Leo Laporte: 看来你不擅长移交工作。

Rasmus Lerdorf :我也不清楚开源的理论,当时也没什么开源的东西,我自己也是后来才想清楚了这些。没过多久,我在多伦多大学找了份工作, 建立一个对话访问系统。我想那大概是 97 年吧,哦,是 96年,偶尔我还能收到一些关于 php 的补丁,有些 bug 是我从来没碰到过的, 我碰到些困难, 有个在日本的程序员给我发了一些补丁,非常酷, 还有有一些在日本的朋友帮我做了咨询方面的工作,但是这并不是经常性的。 一年之后我想通了 , 我的确需要鼓励这种贡献,人们提交了 patch, 我不能接管然后自己再重写, 我应该接收它, 放弃控制。给他人以权力随心所欲的做自己想做的事情。对于大多数开源的开发者来说,这很难,即便在现在,开源项目是他们孩子, 他们应该控制它,但是对于长期发展来说, 你应该放手, 让其他贡献者做他们要做的事情 , 你不能做太多限制。

Leo Laporte: 看来,我们作为用户应该更激进一些,呵呵

Rasmus Lerdorf : 这没关系, 你应该意识到这点,这些人大部分也都是在家里做开源开发的,百分之九十的开源开发者不管他们是做什么。他们把孩子哄上床,为开源项目贡献出两个小时,然后 他们打开自己的邮件,发现一大堆愤怒的信息,全都是"这里有 Bug, 另外这里还有 Bug, 这个 bug 使得我们上百万的电子商务操作无法进行" , 但他们只能说:“好吧,我已经在晚上贡献了2个小时, 这确实不是我应该太过在乎的事情(你的上百万电子商务程序)"。 所以说,人们对这些开源项目的开发者应该给予一些尊重。

Leo Laporte: 开源是如此繁荣,我想说你们这些人才是开源社区的源动力,我们所能做的就是给予你们以应得的尊重。

Chris DiBona : 恩, 我发现 Rasmus 的车子有点脏了,呵呵

Leo Laporte: 呵呵,我愿意为他擦洗车子,我欠他的太多了,我在服务器上运行了那么的 php 程序 ,从日志跟踪程序到 drupal .

Rasmus Lerdorf : 你不欠我什么,不欠我任何东西,我们 php 项目现在有 1100个开发人员。

Chris DiBona : 看来你现在已经把移交工作做的很好了

--------------------------------------------------------------------------------------------

Leo Laporte:  1100 个开发者可不是个小数目啊。

Rasmus Lerdorf :是的, 如果你修复了 PHP 项目的一个bug, 发来一个不错的补丁, 那么PHP 社区就非常欢迎你的到来。

Leo Laporte:  我知道Perl 社区老早就说起开发 Perl 6 了, 不知道 PHP 6 的号角是否已经吹响.

Rasmus Lerdorf :我们不太善于做市场方面的工作, 但是 PHP 6 工作的确正在进行了.

Leo Laporte:  跟我们讲点这方面的事情吧

Rasmus Lerdorf :PHP 6 最大的一部分改进在于对 Unicode 的支持. PHP 6 任何一部分代码都是基于 utf16 编码的.

Leo Laporte:  这大概是 PHP 6 大部分被重写的地方之一吧.

Rasmus Lerdorf :是的, Unicode 很艰深, 我跟 200 多名懂得 unicode 的开发者开过一个会, 其中包括一些日本的开发人员,他们工作于 IBM 公司, 知道很多 ICU 项目的东西. ICU 是 IBM 的 Unicode 项目, 当时 ICU 项目并不是很好, 它太大了. 它的代码比 PHP 的源码还大, 差不多有10倍了吧.

Leo Laporte:  等等, 你说什么, ICU 项目的代码量是 PHP 的10倍

Rasmus Lerdorf :它太庞大了, 太让人吃惊了, 而且它不是模块化的, 这意味着你无法从中取出你所需要的部分. 但是现在 ICU 也发展了, 我们可以取出我们需要的部分, 所以如今在 PHP 项目中加入 ICU 支持是可行的, 这使得 PHP 可以在任何地方完全支持 Unicode , 这是 Php 6 最大的改动, 此外的改进还有“命名空间”等其它特点.

Chris DiBona :那其它的库是否也要因此重写以支持 unicode 呢?

Rasmus Lerdorf :你说的是库和扩展吧, 有一些函数是要重写的, 基本上涉及到传递字符串或者操作字符串的函数都需要重新审核一下, 是的,这是很大的工作量. 大概在年底会有一个alpha 的测试版发行, 这个版本只是说: 大家看看,测试一下, 看看你现有的代码中有多少因为采用这个版本而无法运行, 估计大多数 Php 5 的代码都不会有什么问题, 我们并不担心, 或许你马上就可以利用它实现一些 unicode 的有趣功能. 如果你正确使用它, 熟悉这个版本的过程中就不会有太多的麻烦, 不过也有可能出现一些我们没考虑到的问题, 所以我们希望尽早发布测试, 而不是像某些语言一下等上5年.

Leo Laporte:  我在自己的服务器上运行的是 php4, 顺便说一句, 非常感谢你们的工作, 开发了这么好的产品. 像很多人一样, 我使用的是 Php 4

Rasmus Lerdorf :恩, 它的确工作的很好, 如果你没什么必要的话, 也可以不升级...

Chris DiBona :火是很可怕的( 注解: 5(five) 和 fire 英文发音相同)

Leo Laporte:  哈哈, 是的, 我并不怕火, 呵呵, 我只是不想换版本, 因为它现在工作良好, 是吧?

Rasmus Lerdorf :是不应该害怕升级的, 直到我们认为完全可以抛弃这个版本之前, 我们将继续提供 php 4 的安全补丁. 对于大多数产品来说, 在 php 4 上良好运行的程序都应该在 php5 上运行. 最困难的是那些大型的 ISP, 它们有成百的用户, 上千个运行的 PHP 程序, 其中若是有几个程序无法运行, 这对他们来说,的确很可怕, 如果没人抱怨升级的问题, 的确没这个必要冒险去升级版本. 但是 PHP 5 的确有一些很吸引人的功能, 比如简单 XML 处理支持, Soap 扩展, 相当快的 Soap 处理, 如果你程序中要处理 Web 服务, 需要解析大量 XML  那么用 PHP 4 来处理就相当痛苦了, 这是我们分支出 PHP 5 版本的主要关注点.

Leo Laporte:  好吧, 为了支持 PHP 5 我要去重新编译我的 Apache 了, 你们两个继续谈.

Chris DiBona :好啊, 待会见.

Leo Laporte:  Twit.tv 服务器宕机了, 我一会再来.

Chris DiBona :你可以给 Rasmus 写邮件.

Leo Laporte:  你能给我写代码吗?  Rasmus

Chris DiBona :奇怪, Drupal 好像运行 Php 5 没什么问题?

Leo Laporte:  我也不知道为什么我要运行 php4, 好像Drupal 最新版本 5.1.4 重新编译支持 php5 , 如果没有什么特别的原因, 是否应该将程序运行从 PHP 4 转到 PHP 5 呢?

Rasmus Lerdorf :恩 ...

Chris DiBona :会运行更快一些吗?

Rasmus Lerdorf :也许不会那么快吧, 有一些程序会运行的很快, 有一些程序的运行速度和原来差不多, 这取决于你的代码做什么, 如果你的代码恰巧使用了我们做大量工作优化的部分, 那么速度就会很快, 否则就和原来速度差不多.

Leo Laporte:  让我们来谈谈人们常常说的 PHP 的一些问题吧, 有一些人经常抱怨 PHP 的性能问题, 我从来没碰到这些困扰, PHP 的扩展性很好.

Rasmus Lerdorf :你混淆了两个概念, 性能和扩展性没有什么联系。

Leo Laporte:  是吗? 让我们来谈谈这个.

Rasmus Lerdorf :是的, 性能是单一服务器对单一请求的服务有多快; 而扩展性是指你能扩展的宽度, 比如, 如果你有10万个并发访问, 你如何能将它控制在一定的响应时间之下.

Leo Laporte:  我想两者都很重要,但是扩展性更重要一些

Rasmus Lerdorf :是的, 但是从某方面说, 性能也很重要, 你可以更换一个更快的CPU, 但是无法并排放大量的服务器, 如果单一请求的响应延迟是半秒钟, 那么并排放500个服务器, 除非你有大量的访问请求, 否则每个请求的响应时间还是半秒钟. 性能问题跟响应延迟有关, 你可以在单一服务器上服务于更多的请求, 扩展性则更多与架构有关, 你要确定你所做的不要和某个服务器紧密绑定, 我们在 PHP 中做的很多事情都有这么一个概念叫做"share nothing"的架构(不共享任何东西), 就像一个 "PHP 黑箱", 你接受一个php 请求, 然后处理该请求, 任何关于这个请求的东西都在这个请求结束后消失, 没有什么东西可以跨越请求存在的, 你要建立一个这样的系统, 每个请求都是相互独立存在的, 因为每个请求可能来自不同的服务器, 你可能在一个负载均衡程序的后面放了 500 个服务器, 那么程序也能将照常运行. PHP 的 Session 机制默认是保存在本地的 tmp 目录中的, 但是我们提供了一个很简单的机制将 session 保存在数据库中, 所以我们在 php 中做的任何事情都保证它是可扩展的, 这也是为什么yahoo 和 flick 的程序员采用 php 的原因. 因为扩展性是内建在 php 之中的. 有人说 php 是不可扩展的, 是因为他们不了解如何去实现扩展性. 就我而言, 我们没有碰到任何扩展性的问题, 所以你可能看不到我们关于扩展性方面讨论的文章. 但你不能说, PHP 不可扩展仅仅因为我们没有讨论它的可扩展性问题

Leo Laporte:  哈哈

Rasmus Lerdorf :有时候这真让人头疼. 恩, 关于性能的问题, 你能做的事情不多, PHP 像大多数脚本语言一样, 分为两步访问. 首先是将磁盘上的文本编译为 op-code  , 然后将  op-code  传递给执行程序, 这有点像 Java 的字节码. 我们可以把  op-code  放到缓存中, 比如我们已经用了多年的 APC , 还有其它一些产品. 它们将编译好的  op-code  放到共享内存中, 如果第二次请求 php 脚本的时候, 我们将看到, 嗨, 检查一下共享内存,  这是 inode , 我们的共享内存中是否有这个缓存过这个 inode 块, 如果有的话, 我们可以直接执行共享内存的  op-code , 这将会使得代码提速达30至40 倍之多.

Leo Laporte:  这有点类似 python 的 pyc 字节码, 只是你没有在磁盘上保存编译的版本

Rasmus Lerdorf :是的, 因为性能最慢的地方就是读取磁盘.

Leo Laporte:  这并不能节省多少时间, 是吧?

Rasmus Lerdorf :是节省不了多少,   op-code 本身就是很小的文件, 500 字节和1000 字节在文件系统中可能都是占用一个块, 你从大小上节省不了什么. 相反你应该避免这种磁盘操作, 任何这类操作都是挺耗费时间的. 不经过任何拷贝操作, 直接从共享内存中执行代码是最快的. 如果我们修改了磁盘上的代码, 我们需要告诉 APC , 可能需要重新启动 web 服务器.

Leo Laporte:  这么说系统需要足够的内存以运行程序了

Rasmus Lerdorf :所有高性能的网站都会用到缓存的

Leo Laporte:  这么说我们将为运行 PHP 投入更多的内存了.

Chris DiBona :那么 Zend 提供了些什么, 更好的解析器? 他们确实在销售一些性能优化的产品.

Leo Laporte:  他们也有一些缓存的产品吧

Rasmus Lerdorf :一样的, 他们本身也没有  op-code   缓存, 他们也提供这方面的缓存产品, 你可以选择.

Leo Laporte:  你有自己喜欢的缓存产品吗?

Rasmus Lerdorf :我比较喜欢的是 APC , 不是我创建的它, 别人创建的, 我只是帮着他们让其良好运行. 我需要一个缓存得以开始这方面的工作.

Leo Laporte:  习惯上, 如果你运行一个访问量比较大的网站, 通常都会要用到一个缓存系统.

Rasmus Lerdorf :是的,你应该有一个, 你可以从 Zend 公司购买, 或者试一试开源的缓存系统.

Chris DiBona :APC  是什么意思?

Rasmus Lerdorf :Alternative PHP Cache,  PHP 是开源语言, 所以我们需要一个开源的缓存系统, APC 运行的很好.

Leo Laporte:  不错, 我要在我的服务器上实验一下. 谈谈 PHP 的安全性吧, 你对安全性考虑的有多少?

Rasmus Lerdorf :这么多年有很多讨论 PHP 安全性的问题, 我觉得有一些是正常的, 大多数批评对 PHP 是很不公平.

Leo Laporte:  有很多不好的实现

Rasmus Lerdorf :的确有很多很烂的代码, 我们无法把他们都修复了, 有一些错误的确是我们的问题, 我们的程序确实有 bug , 我们会尽量正确地修复它. 但是还有很多是我们无论如何都无法解决的. PHP 比别的语言跟容易出现这种问题, 因为它比其它语言更容易学习, 也就是说越是缺少编程经验的人越容易采用 PHP , 有一些代码的确写的不那么安全, 结构也不好. 而且 PHP 项目的命名也是个问题, 人们总喜欢用 PHP 来命名自己的项目.

Leo Laporte:  是啊, 宝贝, 这可是用PHP写的. 不用其它名字来命名项目了.

Rasmus Lerdorf :呵呵, 我也不知道为什么我们会有这个问题,  别人就不会起 Python Mailman  这样的名字. 其它语言开发的项目不会起名为 Perl XXX, Python XXX, Ruby XXX , 当然 Ruby on rails 是个例外. 你看, 这么多项目都以 PHP 命名, 他们似乎都想打上 PHP 的标签.

Leo Laporte:  Php Myadmin 也是其中之一, 有很多这种方式命名的项目

Rasmus Lerdorf :任何一个关于这些项目的 bug 都会归到 PHP 头上, 如果 Mailman 出现了安全性的问题, 你的第一反应不是 Python 出了什么安全性问题, 至少通过名字关联不会这么想, 你最多只是说:"Mailman 这程序太蠢了", 如果 PHP 的项目出了问题, 他们就会说:"PHP 又出问题了, 这个语言的确不安全, 看看这些问题吧"

Leo Laporte: 你有什么类似 perl 的一些措施限制程序员去做正确的编程吗?

Rasmus Lerdorf : 我们有很多级别的错误报告机制, 你可以打开开关,如果你访问一些未赋值的变量, 就会出现警告等等。

Leo Laporte: 你在 yahoo 工作

Rasmus Lerdorf :  是的

Leo Laporte: 它们用了很多 php 代码,  你可以说说他们都是在什么地方采用 php 开发的。

Rasmus Lerdorf :  几乎所有 yahoo 网站都采用了吧

Leo Laporte: 是吗? 这倒是可以作为 php 扩展性的一个好的典范, 任何人说 php 扩展性不好的,都可以去看看 yahoo . yahoo 的邮件系统也是用 php 写的吧

Rasmus Lerdorf : 老版本的邮件系统不是基于 php 的。

Leo Laporte: apple 的网站是基于 php 的吗?

Rasmus Lerdorf : 说实在的,我也不知道。

Leo Laporte:它们大部分都是基于 javascript

Rasmus Lerdorf :  apple 的网站很多都是基于客户端的技术,我不知道它们有什么地方用到了服务端的技术, 客户端也不是我所关注的技术。

Leo Laporte:我非常喜欢 Yahoo 的邮件系统, 它可是 ajax 技术运用的一个良好示范啊。太感谢你了,Rasmus,给我们提供了这么好的语言, 可以做许多强大的事情。

Chris DiBona :非常方便

Leo Laporte: 1100 名开发人员, php 社区可真是强大啊, 真让人惊奇。

Chris DiBona : Pretty Handy Processor (Chris 开玩笑解释 PHP 命名)

Leo Laporte: 哈哈,你又来了, 不过这个解释我喜欢

Rasmus Lerdorf : 大概是人们讨厌 Perl 吧。

Leo Laporte: 哈哈, 这个理由我接受。

Rasmus Lerdorf : 对不起,对不起,Larry ( Larry 是 Perl 语言的创始人)

Leo Laporte: 我们确实想采访一下 Larry 。

 

Tags: php, 访谈, 摘要, 程序员

语言包?

本文也是转摘,不过看到它的时候,我想起了discuz的URL解析,discuz在做rewrite的时候,并没有主动都对模版中的链接进行更换,而是在输出前,对于符合规则的那些链接使用rewrite的规范进行了一次批量替换。

这次我转摘的文章也是用了类似的方法,只是他又是.NET处理的,我也不翻译了。知道了原理就行了(和discuz一样,不过这种方法应该只适合做语言包)

原文:

一直以来多语言问题都是个让人头疼的问题,不是这个问题有多难,而是很繁琐,而我们目前的这个项目有点特殊,我希望最大限度的化繁为简,以下是我解决这个问题的方案。
我们的项目有这样两个前提:
1、要支持多语言但最多三种语言,一般情况下就两种语言,所以并没有随时切换语言的要求。
2、我们希望有一种可以初期不用管语言问题,之后统一翻译的方案
基于这么两点,我们提出了这样的方案:
1、初期写程序时不用关心多语言的翻译工作,只要将所有使用到中文的地方都用{}扩上
2、在数据库中Chinese会设置为唯一约束
3、所有的翻译工作会在BasePage中的Render方法中作
4、所有的页面会继承BasePage
5、翻译时会根据当前的语言设置构建以language表中Chinese做key,相应的语言为value的字典,然后查找需要翻译的字符串是不是在字典中,如果不在就生成这一行。

 
数据库设计四个字段

ID,Chinese,English,Other

BasePage源码:

C#代码
  1. using System;  
  2. using System.Data;  
  3. using System.Configuration;  
  4. using System.Linq;  
  5. using System.Web;  
  6. using System.Web.Security;  
  7. using System.Web.UI;  
  8. using System.Web.UI.HtmlControls;  
  9. using System.Web.UI.WebControls;  
  10. using System.Web.UI.WebControls.WebParts;  
  11. using System.Xml.Linq;  
  12. using System.Text.RegularExpressions;  
  13. using System.Text;  
  14. using System.Collections;  
  15. using System.Collections.Generic;  
  16. using System.IO;  
  17. using System.Diagnostics;  
  18.   
  19. /// <summary>  
  20. ///BasePage 的摘要说明  
  21. /// </summary>  
  22. public class BasePage : System.Web.UI.Page  
  23. {  
  24.     //利用Dictionary来筛选所有的多语言标签,然后做替换,可以缓存  
  25.     Dictionary<stringstring> dic;  
  26.     public BasePage()  
  27.     {  
  28.   
  29.     }  
  30.     //需要替换的标签,标签头为数字字母下划线汉字  
  31.   
  32.     static readonly Regex re = new Regex  
  33.         (@"((\{)|(\%7B))[\w\-\+\|u4e00-\u9fa5]+?((\})|(\%7D))",  
  34.         RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace);  
  35.   
  36.     //不需要替换的标签  
  37.     static readonly Regex re_nr = new  
  38.         Regex(@"<NOREPLACE>[\w\W]*?</NOREPLACE>", RegexOptions.Multiline | RegexOptions.IgnoreCase);  
  39.   
  40.     private string RenderTag(ref string content)  
  41.     {  
  42.         if (re_nr.IsMatch(content))//不需要替换标签  
  43.         {  
  44.             StringBuilder sb = new StringBuilder();  
  45.   
  46.             MatchCollection grouplist = re_nr.Matches(content);  
  47.             string[] reList = re_nr.Split(content);  
  48.   
  49.             for (int i = 0; i < grouplist.Count; i++)  
  50.             {  
  51.                 sb.Append(ReplaceTag(ref reList[i]));  
  52.                 sb.Append(grouplist[i].Value);  
  53.                 sb.Append(ReplaceTag(ref reList[i + 1]));  
  54.             }  
  55.   
  56.             content = sb.ToString();  
  57.         }  
  58.         else  
  59.         {  
  60.             content = ReplaceTag(ref content);  
  61.         }  
  62.         return content;  
  63.     }  
  64.   
  65.     private string ReplaceTag(ref string content)  
  66.     {  
  67.         //模板标签{yes},{no},{search}  
  68.         MatchCollection mc = re.Matches(content);  
  69.   
  70.         if (dic == null)  
  71.         {  
  72.             dic = LanguageManager.GetResource();  
  73.         }  
  74.   
  75.         for (int i = 0; i < mc.Count; i++)  
  76.         {  
  77.             //如果数据库中还没有此字符串  
  78.             if (!dic.ContainsKey(mc[i].Value.TrimStart('{').TrimEnd('}')))  
  79.             {  
  80.                  content = content.Replace(mc[i].Value, mc[i].Value.TrimStart('{').TrimEnd('}'));  
  81.   
  82.                 if (!dic.ContainsKey(mc[i].Value.TrimStart('{').TrimEnd('}')))  
  83.                 {  
  84.                     LanguageManager.AddLanguageString(mc[i].Value.TrimStart('{').TrimEnd('}'));  
  85.                 }  
  86.             }  
  87.             else if (dic[mc[i].Value.TrimStart('{').TrimEnd('}')] == null)  
  88.             {  
  89.                 content = content.Replace(mc[i].Value, "$$$$");  
  90.             }  
  91.             else  
  92.             {  
  93.   
  94.                 content = content.Replace(mc[i].Value, dic[mc[i].Value.TrimStart('{').TrimEnd('}')].ToString());  
  95.   
  96.   
  97.             }  
  98.         }  
  99.           
  100.         return content;  
  101.     }  
  102.     protected override void Render(HtmlTextWriter writer)  
  103.     {  
  104.   
  105.         Stopwatch stopwatch = new Stopwatch();  
  106.         stopwatch.Reset();  
  107.         stopwatch.Start();  
  108.         try  
  109.         {  
  110.             //会把页面的输出结果存储在这个StringBuilder中  
  111.             StringBuilder sb = new StringBuilder();  
  112.             StringWriter sw = new StringWriter(sb);  
  113.             HtmlTextWriter htw = new HtmlTextWriter(sw);  
  114.             base.Render(htw);  
  115.             string content = sb.ToString();  
  116.   
  117.             content = RenderTag(ref content);  
  118.   
  119.             //重新写入页面  
  120.             writer.Write(content);  
  121.   
  122.         }  
  123.         catch (Exception ex)  
  124.         {  
  125.             Response.Write(ex.ToString());  
  126.             Response.End();  
  127.         }  
  128.         finally  
  129.         {  
  130.             stopwatch.Stop();  
  131.             Response.Write("runtime:" + stopwatch.ElapsedMilliseconds.ToString() + "ms");  
  132.         }  
  133.   
  134.     }  
  135. }  
这样设计的
优点
1、初期写程序时不用关心多语言的翻译工作,只要将所有使用到中文的地方都用{}扩上
2、省去了大量命名相应文字的工作
3、直接用中文标示要显示到页面的文字,容易理解

缺点
1、如果中文是一样的翻译,而其他语言翻译却不一样时不好解决,但这种情况似乎不常见

————————END————————

缺点就是我说的,只能用来做语言包,呵呵。

Tags: web, 语言包, 数据库