为什么很多人讨厌PHP

幾年前我有回覆類似的問題,核心理念是,當我們只從一個或少數角度來觀看一件事時,往往會忘了另一片風景。

重點是,我們打算用程式語言(PHP)做什麼?這會決定我們看的角度,甚至影響了我們的心態。我曾在公開演講中表示,程式語言對我來說,是個「選擇(Option)」,是用來「解決某個問題」。如同我們不會拿榔頭敲掉螺絲,而是使用螺絲起子。一旦我們受限於只比較「工具」的局部特性時,我們很容易只看到一個工具的缺點,而忘了它的優點。

今天我在網路上看到 Phil Sturgeon 在 Quora 針對此問題的回答,同時也同步在他的網誌,分享給大家。

Phil 認為很多人有各種不同的理由「討厭」PHP,或至少看衰它。其中有一些是有根據的,有些則否。

1. Inconsistent haystack / needle

Phil 舉的第一個例子是「不一致的 haystack / needle」。

舉個 PHP 中的兩個內建函式:

  • in_array($needle, $haystack)
  • strpos($haystack, $needle)

很多人批評函式參數的 haystack 及 needle 在不同的情況下的順序不一致,這導致開發者很可能要「硬背」這些 API。

Phil 指出,其實 PHP 的函式設計是有規則的。如果 haystack 處理的是 array,則順序是 needle, haystack;反之若是 string,則順序是 haystack, needle。

2. PHP is a HTML file, with logic

很多人認為 PHP 與 HTML 的混用規則是很奇怪的設計。

Phil 指出,PHP 在起初設計上就是預設檔案是個 HTML,只是中間可以嵌入一些 PHP 的邏輯處理。我們也不能否認的是,在當時的那個時代,這個設計使得 PHP 使用率得以快速成長。

但也不能否認的是,這個現象在現代看來有些不合味口,所以在未來的 PHP 6 將會引入新特性來讓開發者得以解決這個問題。

3. No standards

在 PHP 的世界中有太多的 Web framework,每個都有著自己的標準,例如很多人會爭論使用 snake_case 還是 camelCase。最近這個現象也開始舒解了,因為有 PHP-FIG 組織制定了相關的遵循標準。

4. Lack of Quality Packages

另外很多人批評 PHP 沒有夠好的套件管理工具。例如我們知道,

  • Node.js 有 NPM
  • Ruby 有 Bundler/Gems
  • Python 有 PIP
  • Perl 有 CPAN

而過去的 PHP 只有難用的 PEAR。相對好用的 PHP 套件管理工具也不是沒有,只是過於分散不集中。例如,

  • CodeIgniter 的 Sparks
  • FuelPHP 的 Cells
  • Laravel 的 Bundles
  • CakePHP 的 Bakery
  • ZF2 的 Modules

Phil 認為這個現象將會也會得到舒解。因為除了 PHP-FIG 組織制定的 PSR-0 標準外,也有 Composer 團隊推出標準的套件管理計畫。

5. Misconception

Phil 指出(編者註: Phil 同時也是 Ruby 使用者),很多 Ruby 開發者對 PHP 的批評認知還停留在 PHP 4 的時代。其實 PHP 5 已改進非常多,甚至 PHP 5.3 是一個大躍進。他認為很多人的評論還停留在 7 年前的 PHP。

Phil 同時也說,有些人說 PHP 沒有內建 Web server 是個很糟糕的事,但好消息是從 PHP 5.4 開始就內建 built-in web server 功能了。

6. You were doing it wrong

Phil 指出,很多人會說「You can mix MySQL, HTML and PHP in the same files. PHP is disgusting!」(編者譯: 「你可以把 MySQL, HTML 及 PHP 同時放在一個檔案裡面,可見 PHP 多麼噁心」)。

但 Phil 認為這個缺點可以由 PHP Web framework 獲得解決,同時他也認為如果 Ruby 開發者在不使用 Sinatra 或 Rails 時是怎麼解決這個問題的?或者 Node.js 開發者不使用 Express 或 CanJS 時又是怎麼解決的?(編者譯:Phil 指的應該是「不要拿程式語言(PHP)來和 Web framework (Rails 或 Express) 來比較」)

7. Elitism

Phil 感慨的指出,現在很多人認為「不使用 PHP 的人才酷」(編者註:Phil 言下之意不知是否也指「不要以為使用 Rails 或 Node.JS 就覺得很潮」?)

除了批評之外,我們該想想,「為什麼現在還有那麼多人使用 PHP ?」。Phil 認為「沒意外的話,就是氣勢(Momentum)」,他說根據統計,證明就是很多人使用 PHP,也不否認他仍然使用 PHP 的原因就是,相較於 Ruby、Python 及 Node.JS 而言,PHP 仍然擁有最大的市場。

最後 Phil 認為,很多開發者都在追求「完美的語言」,但答案是「世界上沒有完美的工具」,因此沒有任何人應該「討厭」任何程式語言。

转载自:http://blog.gcos.me/2012-12-04_phil-sturgeon-anwser-why-some-people-hate-php.html

PHP中的二进制位运算和权限存储

在很多系统的权限/选项设置中 很多都用到了位运算的方法来存储多种标志位。这样可以节省字段。一个字段只需要一个数字 就可以标识很多种设置和信息。

举例 dicuz的帖子表的status字段,官方预留了16个标志位(0×0000 – 0xFFFF) 即216

目前规划使用了只有8个标志位,如下

0000 0000 0000 0001 是否缓存帖子位置信息
0000 0000 0000 0010 是否回帖只对管理人员和发帖者可见
0000 0000 0000 0100 是否抢楼贴
0000 0000 0000 1000 是否倒序查看回帖
0000 0000 0001 0000 是否存在主题图章标志位
0000 0000 0010 0000 回复是否通知作者
0000 0000 0100 0000 是否推送到QQ空间
0000 0000 1000 0000 是否推送到腾讯微博

这8种状态可以使用一个数字来同时表示,节省了字段

那么这种东西的原理是什么呢

这个我们可以复习一下的位运算单算法

例子 名称 结果
$a & $b And(按位与) 将把 $a 和 $b 中都为 1 的位设为 1
$a | $b Or(按位或) 将把 $a 或者 $b 中为 1 的位设为 1
$a ^ $b Xor(按位异或) 将把 $a 和 $b 中不同的位设为 1
~ $a Not(按位非) 将 $a 中为 0 的位设为 1,反之亦然
$a << $b Shift left(左移) 将 $a 中的位向左移动 $b 次(每一次移动都表示“乘以 2”)
$a >> $b Shift right(右移) 将 $a 中的位向右移动 $b 次(每一次移动都表示“除以 2”)

比如

与运算

14 = 0b1110

11 = 0b1011

那么 14 & 11 = 0b1110 & 0b1011 = 0b1010 = 10

或运算

还是上面那个例子

14 | 11 = 0b1110 | 0b1011 = 0b1111 = 15

异或运算

14 ^ 11 = 0b1110 ^ 0b1011 = 0b0101 = 5

非运算

非运算比较特殊 涉及到符号 这里要说一下补码 反码 原码的概念

1.二进制最高是符号位 0是正数 1表示负数

2.正数的 原码 反码 补码 都一样(我上面没有单独算补码的原因 ,正数补码和反码一样)

3.用二进制表示一个数 这个码 就是原码 比如 14的原码就是 1110

4.负数的反码 等于 他符号位不变 其他取反,而负数的补码等于他的反码+1

5.计算机运算的时候 全都是以补码的形式来运算的 不管正负数

那么

1 是正数,那么他的原码 0001 = 反码 = 补码 = 0001 =>取反 后补码1110 <=反码 1101<=原码1010

那么这个符号位是1就是负数 也就是010代表的负数就是-2 也就是 ~1 = -2

左右位移运算

1<< 2 1的补码 00000001 移动2位 00000100 正数的反码 补码 原码 都一样 所以 是个4

负数的计算过程相同 不再赘述 左移也类似 4>>2 就是1

其实可以理解为右移在十进制的表现上就是乘以2 左移 在十进制的表现上就是除以2


那么回到本文正题 如何用一个数字来标识这些权限位呢?

以刚才discuz的帖子表达status字段为例,检查帖子回复是否通知作者 就看二进制上第六位是否是置位为1 那么怎么检查呢?就是用上面我们提到的与运算。

与运算是将把 $a 和 $b 中都为 1 的位设为 1。那么假设

$a=36=0b 0010 0100

$b=0b 0010 0000

$a&$b = 0b 0010 0100 & 0b 0010 0000 = 0b 0010 0000 = 32 = 26-1 = 25

因此 检查,某个数代表的第N个权限标志位有没有置位(是1) 只要选择该数与仅该标志位置位的操作数2N-1进行与运算即可,相反要计算某个标志位被置位的数字 只要选择合适的操作数进行或运算即可。我们可以看discuz对此的实现:

function getstatus($status, $position) {
    $t = $status & pow(2, $position - 1) ? 1 : 0;
    return $t;
}

function setstatus($position, $value, $baseon = null) {
    $t = pow(2, $position - 1);
    if($value) {
        $t = $baseon | $t;
    } elseif ($baseon !== null) {
        $t = $baseon & ~$t;
    } else {
        $t = ~$t;
    }
    return $t & 0xFFFF;
}

注意 写这段代码的人显然受到了C的影响 其实 $a & ~$b 和 $a ^ $b 是等效的 只不过 ^是PHP的写法 另外 pow(2, $position – 1)换成 1 << ($position -1) 其实更好理解。

转载自:http://blog.ihipop.info/2013/01/3309.html

PHP语言的精华

我不擅长布道,因为我总是认为人家书上写得东西比我写得好多了.可是我却想把一些简单的道理说一下,因为总有人问我,那我就说几句.

PHP有很多不好的地方,比如说使用$符作为变量的一部分,大量使用->和=>作为分隔符或者引用之类的,并且它的方法并不面向对象,而对象却不能少了过程式方法,它又不像Python那样,方法本身也是对象,同时方法的参考顺序也没有统一的设计,我天天写PHP都要没事就查文档去看substr, strpos, strrpos这些东西.但任何语言都有问题,而PHP却有臫优秀的一面,提提它的精华吧.

第一条精华:简单.

PHP是极其简单的语言,虽然说你可以把PHP复杂化,但是PHP的简单是不需要解释的,也不需要争论的.只要想着PHP在正常情况下会一行一行向下执行,任何人都能够简单地入手.

第二条精华:深入.

不要认为PHP不能做复杂的东西,看看Symfony2框架就明白了,它是一个让PHP完全面向对象的框架,用它能做很多大家伙.

第三条精华:Web+CLI

现在都是PHP5.4的年代了,PHP的GC已经很不错了,你可以在CLI下面写脚本,就像Python和perl做的那样.

第四条精华:扩展

有啥不够用的东西,用C顶上,没有解决不了的问题.

第五条精华:资源

在Web上有大量超乎想像的PHP资源,反正我认为在Web领域要远超其他语言(JavaScript这货不算)

第六条精华:成熟产品

Drupal, WordPress, Joomla, media wiki, tiki, mantis等等,还有crm相关的,国内也有phpwind, discuz, 方维等各家都在使用PHP做产品,大部分都易于修改扩展.

就这六条,应该满足了.别黑我大PHP了.

转载自:http://saharabear.com/weblog/?p=1718

乱谈PHP

新年第二天,从今天以后的一年里都不再数新年第几天。

整体来讲,我不算一个PHP程序员,因为我的入门语言是C和Java,虽然当时一直不明白为什么要用C,因为做网站用Java比用C写CGI要好得多。

再后来学习的是Python,因为这东西在04到05年不大火,却有很多老外希望用这种语言写东西,会的人少,大赚一笔,为此还去读了一部分Python的代码。

再后来就是写商业的Java项目,从Struts+Spring+Hibernate到Struts2再到Wicket+Guice+IBatis还有Wicket+EJB3最后用上Grails和该死的Groovy,我终于烦了。

其间,一直在写PHP。

为什么我很少参与PHP的活动呢?比如我参与的PHP交流不多,看过的PHP代码也不多,到今天还是没学会怎么真正使用Drupal,只能简单做一做模板。其实就是因为PHP这门语言太好了,根本不用多花时间去研究它的实现,只要有一本手册,无论是Web还是Cli都能够很好地运行,不管是直接用过程式,还是大量利用现在的5.4的新特性,都很容易写好代码,虽然有一些时候,需要工具来监控一下执行过程的内存问题,但比起其他语言来讲,PHP的确是极其容易学习的。

就因为这个,我提到PHP的次数不多,因为不太必要提,因为它易学易用。

但是,最近总有人:又黑我大PHP。

所以,我决定宣布我就是PHP程序员,我不打算再当杂牌程序员,不再说自己是Python程序员或者Java程序员了,因为那样,我再次对别人说:又黑我大PHP的时候,他们就不能再说:谁让你一写Python的来掺和,或者说:你一Java端的,你哪头的。

所以,我是PHP程序员。

Over。

转载自:http://saharabear.com/weblog/?p=1703

Mobile_Detect一个基于PHP的移动(手机)设备检测类

一个用于检测移动设备的轻量级PHP类。

Mobile_Detect是一个用于检测移动设备的轻量级PHP类,他使用User-Agent字符串同时结合特定的HTTP头部信息来检测一个移动环境。

从2.0开始加入了对平版设备的检测功能。

使用方法

实例化一个类:

<?php
include 'Mobile_Detect.php';
$detect = new Mobile_Detect();

基本使用,检查是否移动或平版设备:

<?php
if ($detect->isMobile()) {
    // Any mobile device.
}

<?php
if($detect->isTablet()){
    // Any tablet device.
}

检查是否一个指定的操作系统:

<?php
if($detect->isiOS()){
    // Code to run for the Apple's iOS platform.
}

<?php
if($detect->isAndroidOS()){
    // Code to run for the Google's Android platform.
}

同样其它的可用方法有 isIphone(), isIpad(), isBlackBerry(), isKindle(), isOpera(),完全的方法列表可以看 demo.php 文件。

另外一种 is() 检测方法(beta):

<?php
$detect->is('Chrome')
$detect->is('iOS')
$detect->is('UC Browser')
[...]

github地址

转眼PHP已经更新到5.4.9和5.3.19,还有PHP 5.5 Alpha1发布

PHP 5.3和5.4都是修复一些bug,重要的是PHP 5迎来了第一个Alpha版本。

看看PHP 5.5的一些新特性(不完全列表):

  • support for Generators (支持生成器)
  • a new password hashing API (密码hashing函数)
  • support for finally in try/catch blocks (try/catch代码块支持finally)
  • support for list() in foreach
  • constant array/string dereferencing
  • ext/intl improvement

还有一项是不再支持Windows XP和2003

PHP使用gettext实现i18n (internationalization)国际化

i18n是英文单词internationalization的首字母”i”和末字母”n”的缩写,中间的18代表省略(缩写)了18个字母。

gettext是PHP的一个函数库,主要函数有

  • bind_textdomain_codeset
  • bindtextdomain
  • gettext
  • textdomain
  • dgettext
  • ……

我们首先要先搞明白一些概念,就能很容易的理解这些函数了。

  • .po文件

    把英文内容翻译成本地内容的文件,文件格式:

    msgid "英文内容"
    msgstr "本地内容"
    

    比如:

    msgid "hello, world!"
    msgstr "你好,世界!"
    

    这样我们在程序中使用 gettext("hell, world!"),如果设置成显示中文的话就会显示“你好,世界!”,英文的话就会显示”hello, world!”

  • .mo文件

    .po文件是我们编辑的源文件,就像我们写的代码一样,.mo文件是编译过的二进制文件,gettext读取的就是.mo文件,因为程序读取二进制的效率要高一些。

  • 函数中的domain

    domain就是.mo的文件名,一般.po和.mo的文件名是一致的,除了扩展名不样。bindtextdomain的第一个参数就是.mo的文件名, 比如我们要用default.mo文件,那么bindtextdomain第一个参数就是default,第二个参数是default.mo文件的路径。

  • textdomain

    程序中可以设置绑定多个.mo文件,textdomain是设置默认的.mo文件,比如设置default.mo文件为默认 textdomain('default')之后 就可以使用gettext函数来实现多语言了。

  • dgettext

    上面我们知道gettext函数使用的是默认的.mo文件,那么dgettext函数就是指定.mo文件,二个参数,第一个是.mo文件名,第二个参数同gettext函数的第一个参数一样。

  • bind_textdomain_codeset

    指定.mo文件的编码,一般我们使用utf-8,就需要调用这个bind_textdomain_codeset,你的.po文件是utf-8,那么.mo文件也是utf-8,二个文件会保持一致, 不指定编码的话使用gettext或者dgettext就会是乱码。

  • poedit编辑器

    poedit就是专门编辑.po文件的编辑器软件,他只能翻译内容,不能添加内容。

  • 目录结构

    对于.mo文件是的位置是有一定要求的,比如我们想把.mo文件统一放在./locale目录,可以使用函数 bindtextdomain('default', './locale'); 来设置, 那么我们的中文default.mo文件的位置必须是 ./locale/zh_CN/LC_MESSAGES/default.mo ,zh_CN是中文,LC_MESSAGES是固定的,为什么要有他我也不清楚。

  • setlocale函数

    这个函数是语言切换的核心,比如上面我们有一个中文的翻译文件default.mo保存在zh_CN目录下面,我们只需要调用 setlocale(LC_ALL, 'zh_CN');  即可显示我们在default.mo翻译过的内容。关于第一个参数可以查看php setlocale的文档,这里就不说了。

还有什么问题不明白的可以通过评论告诉我哦。

openSUSE 12.1升级到openSUSE 12.2

不管你是用界面升级还是用命令行升级,都需要以下几个步骤:

  1. 禁用目前12.1的源
  2. 添加12.2的源
  3. 执行升级

下面就说一下使用命令行升级的过程,因为我使用的这这种方式

  1. 禁用当前的源

    zypper modifyrepo --all --disable
    
  2. 添加12.2的源

    zypper addrepo --name "openSUSE-12.2 OSS" http://download.opensuse.org/distribution/12.2/repo/oss/ repo-12.2-oss
    zypper addrepo --name "openSUSE-12.2 Non-OSS" http://download.opensuse.org/distribution/12.2/repo/non-oss/ repo-12.2-non-oss
    zypper addrepo --name "openSUSE-12.2 Updates" http://download.opensuse.org/update/12.2/ repo-12.2-update
    
  3. 执行系统升级

    zypper ref
    zypper dup
    

升级之后我的google-chrome打不开了,重新安装一下解决,其它没有问题。

openSUSE 12.2 已发布

亲爱的用户,开发者和各界极客们 – openSUSE 12.2 为您准备好了! 两个月额外的稳频工作打造了一个恒星级的发行版,精彩频频,稳健如一!

openSUSE 最新版,世界上最强大最灵活的 Linux 发行版通过 Linux 3.4 的快速存储层和 glibc 与 qt 中的加速函数为您带来了 全线加速,如雨丝般平滑的桌面,风驰电掣般的响应速度!基础架构的进化带来了 新的成熟技术 如 GRUB2 和 Plymouth,并向改进和简化的 UNIX 文件系统结构迈出了第一步。用户还会为无处不在的 已有特性打磨 带来的感觉所惊艳。新兴的 Btrfs 文件系统带来了改进的错误处理和恢复工具;飞速发展的 GNOME 3.4 带来了所有程序的平滑滚动和重制的系统设置与联系人管理;XFCE 带来了增强的应用程序查找器。

“我们为此版本的 openSUSE 自豪,我们恪守了 openSUSE 一贯的高质量体系。”—— openSUSE 董事会的安德鲁·瓦法说。“我们过去两年的增长造成的发布周期上的延迟意味着我们必须进行一些扩容。现在 12.2 已经发布了。”

  • 性能

从内核到桌面,openSUSE 12.2 都实现了提速:Linux 3.4 有了一个快速存储层来防止大量传输时的阻塞。glibc 2.15 基础库改进了许多函数的性能,尤其是在 64 位机器上表现更好。Systemd 44 启用了快速引导。并且基于 Qt 4.8.1 编译的 KDE 4.8.4 让桌面响应更快。

  • 进化

openSUSE 采用成熟应用程序的最新版来构建 Linux 发行版。GRUB2 引导加载器 目前设为默认,可执行包目前位于 /usr/bin,引导和关机时, Plymouth 0.8.6.1 提供了无闪烁的切换和动人的动画。

  • 打磨

GNOME 3.4 引入针对所有程序的平滑滚动,重制的系统设置应用和美化的联系人管理器。XFCE 4.10 改进了应用程序查找器,也允许了垂直面板。Dolphin 文件管理器更漂亮更快了。

  • 创新

XOrg 1.12 引入了多点触摸输入设备和多点部署。谋智火狐 14 支持了最新的网络技术。 llvmpipe 软件 3D 渲染器在即使没有 3D 硬件的情况下对 Gnome Shell 和虚拟机也实现了混成。GIMP 2.8 和 Krita 2.4 让图片处理和原生多媒体绘画能够与商业工具相媲美。Tomahawk 播放器 使您听音乐也能与朋友互动。

  • 稳定

LibreOffice 3.5 继续精炼自由办公套件体验,提供了许多新功能和改进。KDE 4.8.4 的电子邮件和日历应用改进了稳定性,下一代 btrfs 文件系统 也改进了错误处理和提供了恢复工具。

  • 管理

3.4 内核现允许设定整个进程组的 CPU 使用率上限。新版 systemd 提供了一个看门狗功能,能够监视控制下的服务,还提供了一个新的进程管理工具。系统管理员也能从这套新的 数字取证/事故响应 工具中获益。

  • 新奇

一系列重量级科学工具为 openSUSE 提供了诸如数字计算,绘图和可视化数学应用程序。Stellarium 天文模拟器让您不用望远镜就能探索夜空。程序员们得到了 1.0.2 版的谷歌 Go 语言,和 GCC 4.7.1 与 Qt Creator 2.5 带来的最新 C++ 语言标准。

在这些技术革新之外,文档组对参考手册做出了重要修订,并引入了让社区贡献者更容易参与 openSUSE 文档撰写的设施。

支持和发布

依旧,此版本将在至少两个发布周期 + 两个月内提供支持。目前,openSUSE 12.3 的计划周期是 6 个月,由于 12.2 发布推迟了两个月。由于项目目前正在 重新思考它的工程和发布环节,该计划未来可能有变。