译者:本文其实非常老,大约是2002年的文章,主要针对的是PHP4的版本,其实文中很多问题都随着PHP的不断发展而解决了。有批评才有进步嘛。 Edwin Martin <edwin@bitstorm.org>. 翻译:ShiningRay @ Nirvana Studio 我在过去的四年里一直致力于PHP应用的开发。PHP确实十分容易编写。但是PHP也有一些十分严重的缺陷。 下面我会给出我的理由,为什么PHP不适合于比小型业余网站更大的网站。 1. 对递归的不良支持 递归是一种函数调用自身的机制。这是一种强大的特性可以把某些复杂的东西变得很简单。有一个使用递归的例子是快速排序(quicksort)。不幸的是,PHP并不擅长递归。Zeev,一个PHP开发人员,说道:“PHP 4.0(Zend)对密集数据使用了栈方式,而不是使用堆方式。也就是说它能容忍的递归函数的数量限制和其他语言比起来明显少。”见bug 1901。这是一个很不好的借口。每一个编程语言都应该提供良好的递归支持。 2. 许多PHP模块都不是线程安全的 在几年前,Apache发布了Web服务器的2.0版。这个版本支持多线程模式,在这个模式下,软件一个一部分可以同时运行多个。PHP的发明者说PHP的核心是线程安全的,但是非核心模块不一定是。但是十次有九次,你想要在PHP脚本中使用这种模块,但这又使你的脚本不能合适Apache的多线程模式。这也是为什么PHP小组不推荐在Apache 2 的多线程模式下运行PHP。不良的多线程模式支持使PHP常被认为是Apache 2依然不流行的原因之一。 请阅读这篇讨论: Slashdot: Sites Rejecting Apache 2?. 3. PHP 由于商业原因而不健全 通过使用缓存,PHP的性能可以陡增500%[见基准测试]。那么为什么缓存没有被构建在PHP中呢?因为Zend——PHP的制造者,它在销售自己的Zend Accelerator,所以当然,他们不想抛弃自己的商业产品这块肥肉。 但是有另一个可选择的: APC. (Zend后来推出Zend Optimizer,免费的加速器——译者) 4. 没有命名空间 设想某个人制作了一个PHP模块用来阅读文件。模块中一个函数叫做read。然后另一个人的模块可以读取网页的,同样包含一个函数read。然后我们就无法同时使用这两个模块了,因为PHP不知道你要用哪个函数。 但是有一个很简单的解决方法,那就是命名空间。曾经有人建议PHP5加入这个特性,但不幸得是他没有这么做。现在,没有命名空间,每个函数都必须加上模块名作为前缀,来避免名称冲突。这导致了函数名恐怖得长,例如xsl_xsltprocessor_transform_to_xml让代码难于书写和理解。 5. 不标准的日期格式字符 很多程序员对 日期格式字符 都很熟悉,它是从UNIX和C语言中来的。其他一些编程语言采用了这个标准,但是很奇怪的,PHP有它自己的一套完全不兼容的日期格式字符。在C中,“%j”表示一年中的当天,在PHP中他表示一个月中的当天。然而使事情更混乱的是:Smarty (一个很流行的PHP模版引擎)的 strftime 函数和 date_format 函数,却使用了C/UNIX的格式化字符。 6. 混乱的许可证 你也许认为PHP是免费的,所有的在手册中提到的PHP模块也是免费的。错了!例如,如果你想在PHP中生成PDF文件,你会在手册中发现两个模块:PDF 和 ClibPDF。但是这两个都是有商业许可证的。所以,你所使用的每个模块,你都要确保你同意他的许可证。 [...]
注意! 本指南针对cake_0.9.1_dev 发布版不是SVN的版本。请不要把指南的代码改成于SVN一样。 Cake 指南:建立一个简单的Blog 这是一个还在不断变化的一个应用框架的指南。文章中的东西可能可以运行,但是如果有些东西无法运行,请您先仔细阅读 API 文档 。错误报告对我们很有价值,所以,请报告任何影响您使用的地方。 注意:命名方法的约定已经从下划线_风格变成了骆驼回归法则。所以,在我们目前的发布版中link_to()已经变成linkTo()。 默认Cake目录结构一览 在本篇指南中,我们将一起使用Cake来创建一个简单的Blog应用。我假设你对PHP十分了解,可以在你的系统中游刃有余(包括从命令行中运行程序),同时已经有一个配置好的开发服务器环境,例如运行PHP的 XAMPP。 下载 下载最新的Cake 包并解压缩到你的Web服务器的DOCUMENT_ROOT下(因为本文是指南的缘故,我假设他可以从http://localhost/cake/下访问)。你可以看到基本的目录结构。 创建数据库 创建一个用来存放Blog帖子的表格,并且初始化一些数据。以下是SQL语句: CREATE TABLE posts ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, title VARCHAR(50), body TEXT, created DATETIME DEFAULT NULL, updated DATETIME DEFAULT NULL ); INSERT INTO posts (title,body,created) VALUES (‘The title’, ‘This is the post body.’, NOW()); INSERT [...]
在数据库中存储层次数据 作者:Gijs Van Tulder 翻译:ShiningRay @ NirvanaStudio 无论你要构建自己的论坛,在你的网站上发布消息还是书写自己的cms [1]程序,你都会遇到要在数据库中存储层次数据的情况。同时,除非你使用一种像XML [2]的数据库,否则关系数据库中的表都不是层次结构的,他们只是一个平坦的列表。所以你必须找到一种把层次数据库转化的方法。 存储树形结构是一个很常见的问题,他有好几种解决方案。主要有两种方法:邻接列表模型和改进前序遍历树算法 在本文中,我们将探讨这两种保存层次数据的方法。我将举一个在线食品店树形图的例子。这个食品店通过类别、颜色和品种来组织食品。树形图如下: 本文包含了一些代码的例子来演示如何保存和获取数据。我选择PHP [3]来写例子,因为我常用这个语言,而且很多人也都使用或者知道这个语言。你可以很方便地把它们翻译成你自己用的语言。 邻接列表模型(The Adjacency List Model) 我们要尝试的第一个——也是最优美的——方法称为“邻接列表模型”或称为“递归方法”。它是一个很优雅的方法因为你只需要一个简单的方法来在你的树中进行迭代。在我们的食品店中,邻接列表的表格如下: 如你所见,对每个节点保存一个“父”节点。我们可以看到“Pear [4]”是“Green”的一个子节点,而后者又是“Fruit”的子节点,如此类推。根节点,“Food”,则他的父节点没有值。为了简单,我只用了“title”值来标识每个节点。当然,在实际的数据库中,你要使用数字的ID。 显示树 现在我们已经把树放入数据库中了,得写一个显示函数了。这个函数将从根节点开始——没有父节点的节点——同时要显示这个节点所有的子节点。对于这些子节点,函数也要获取并显示这个子节点的子节点。然后,对于他们的子节点,函数还要再显示所有的子节点,然后依次类推。 也许你已经注意到了,这种函数的描述,有一种普遍的模式。我们可以简单地只写一个函数,用来获得特定节点的子节点。这个函数然后要对每个子节点调用自身来再次显示他们的子节点。这就是“递归”机制,因此称这种方法叫“递归方法”。 <?php // $parent 是我们要查看的子节点的父节点 // $level 会随着我们深入树的结构而不断增加, // 用来显示一个清晰的缩进格式 function display_children($parent, $level) { // 获取$parent的全部子节点 $result = mysql_query(‘SELECT title FROM tree ‘. ‘WHERE parent=”‘.$parent.’”;’); // 显示每个节点 while ($row = mysql_fetch_array($result)) { [...]
翻译:ShiningRay @ NirvanaStudio 原文地址:http://wiki.ciaweb.net/yawiki/index.php?area=DB_Table 什么是 DB_Table? DB_Table 是一个用于访问数据库表的面向对象接口。作为一个PEAR DB类的一个 包装,它提供了一些帮助你构建自动的创建、插入、更新和选择功能的方法。同时还有利用 HTML_QuickForm 自动构建输入表单的方法。 DB_Table提供了什么? DB_Table 提供了: 一个嵌在类属性中的模式描述系统,包括: 列定义 索引定义 标准查询 创建HTML_QuickForm元素的属性 从描述的模式自动创建表 一个抽象的API这样即便你改变了数据库后台也不需要改变你的PHP调用。这套API扩展了PEAR DB的功能,同时包含: 用于根据预定义的SQL查询来获取一个结果数组的select() 方法 用于根据预定义的SQL查询来获取一个PEAR DB_Result 对象的selectResult() 方法 create(), insert(), update(), 和 delete() 方法 自动模式检验 根据描述的表模式进行插入和更新字段时的自动检验 时间和日期数据类型抽象,覆盖了数据库的原始数据类型 … 即使你更改了数据库的后端,也无需修改你的查询。 不需要通过类型转换方法来改变查询的值。 当你插入或者更新列时,DB_Table 根据DB_Table 数据类型自动检验数据(datatype automatically (对所有的数据类型: integer, string,等等.). 根据描述的模式自动创建HTML_QuickForm元素,利用以下方法: getForm() 获取整个表单对象,有HTML_QuickForm元素和规则。 getFormGroup() 获取一组HTML_QuickForm元素。 getFormElement() 获取单一的HTML_QuickForm元素 [...]