科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件PHP沉思录

PHP沉思录

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

PHP的工作模型非常特殊。从某种程度上说,PHP和ASP、ASP.NET、JSP/Servlet等流行的Web技术,有着本质上的区别。

作者:左轻侯 2007年7月11日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
但是,PDO还有一个更重要的问题没有解决,那就是对数据集的抽象。
   无论是ADO还是JDBC,除了提供统一的数据库访问接口以外,也提供了对数据集的抽象。也就是说,在通过ADO/JDBC取回数据集结果以后,这些数据集以统一的格式被存放在RecordSet/RowSet对象中,业务逻辑代码只需要与数据集对象进行交互即可。对数据集进行抽象的直接后果,是彻底地分离了业务逻辑层和数据库访问层的代码,并且也在某种程度上起到了OR Mapping的效果。
   自从ADO.NET出现后,数据集的抽象又有了一次不小的进步。和ADO相比,ADO.NET中的DataTable/DataSet类的主要新特性如下:
  
    非连接性。在传统的ADO模型中,数据集需要占用一个数据库连接,直到所有工作完成。一旦连接被关闭,数据集的内容也就失效了。ADO.NET中的数据集是非连接的,也就是说,当连接被关闭后,数据集中的内容仍然保存。这种非连接性带来的直接后果是,数据库连接可以被最大限度地利用,因为一旦工作完成就可以将连接返回到数据库连接池中。(ADO也支持非连接的数据集,但是需要程序员自己实现,而ADO.NET的数据集在本质上就是非连接的。)
    自描述性。ADO.NET中的数据集是完全自我描述的,而且具有完备的metadata,其内容不但可以从任何特定的数据库生成,而且可以由代码动态生成。DataSet可以跟踪数据的变化,并完成相应的操作。
    互操作性。由于非连接性和自描述性,ADO.NET中的数据集可以非常方便地在网络之间进行传输。DataSet可以序列化/反序列化为XML或其他特定的格式。这样,DataSet不但可以用于同一平台的分布式网络环境,而且可以用于异构网络环境。
  
   Java从J2SE 5.0开始内置了CachedRowSet,其原理和ADO.NET的数据集类似。Borland开发的用于取代BDE的新一代数据库引擎dbExpress,其改进也与此类似。
   与之对比,PHP中对数据集的支持显得非常原始。无论是传统的API还是PDO,取回的数据仅仅表现为数组,并且没有任何缓存机制。这意味着,在所有需要访问数据集的地方,都必须频繁地使用直接访问数据库的API。下面是一个使用mysql API的例子:
  
   $link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
   if (!$link) {
   die('Could not connect: ' . mysql_error());
   }
   mysql_select_db("justtest");
   $result = mysql_query("SELECT id, username FROM userinfo ORDER BY ID");
   while ($row = mysql_fetch_array($result)) {
   echo $row['id']." | ".$row['username']."<br/>";
   }
   mysql_close($link);
  
   这样做的后果是业务逻辑和访问数据库的代码无法分离,在规模较大的系统中尤其严重。
   就作者所知,PHP官方没有提供支持抽象数据集的计划。但是,自己实现这样一个数据集并不是一件难事。作者参照ADO.NET的架构,使用纯PHP代码编写了一个规模非常小的数据抽象类库,姑且称之为MyPDO。MyPDO大约有1300行代码,在几个真实项目中工作得很好。由于篇幅所限,本文不列出它的所有代码,仅仅给出几个最主要的类的描述:
  
   &#61548; DataAdapter接口:定义了所有与数据库操作相关的方法。
   &#61548; ConceptDataAdapter类:实现了DataAdapter,封装了访问特定数据库的代码。如MySqlDataAdapter。
   &#61548; DataSet类:实现了自描述的抽象数据集,与具体数据库无关。可以自我跟踪数据的变化。
   &#61548; SqlCommandBuilder类:可以跟据DataSet类的内容,自动实现Insert、Update、Delete等操作。
  
   下面是MyPDO的一个典型应用:
  
   $Conn = new MySqlDataConnection(new ConnectionInfo("localhost", "mysql_username", "mysql_password", "justtest", "gbk"));
   $Da = $Conn->GetDataAdapter();
   $Da->SetSqlString("SELECT id, username FROM userinfo ORDER BY ID");
   $Ds = new DataSet();
   $Da->Fill($Ds);
   $Conn->Disconnect(); // 关闭数据库连接,但$Ds仍然保存数据内容
   echo $Ds; // 调用DataSet的__tostring()方法,格式化输出内容
  
   通过替换MySqlDataConnection,可以以最小的成本实现不同数据库之间的切换。
   由于上文中讨论过的PHP的工作模型,通过MyPDO实现的缓存在性能上获得的好处有限。但是,在采用Memcached的解决方案中,MyPDO还是能够带来很大的便利。因为只有基于非连接方式的数据集,才可能在Memcached这样的内存池中被缓存。
   另外,由于MyPDO中的DataSet是自描述的,内置了WriteToXml和ReadFromXml方式,它无需程序员编码就可以保存为XML或从XML中还原,在网络上甚至异构平台之间进行传输和识别。在电子商务领域中,这个特性是非常有用的。

查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章