从PHP访问数据库的最佳方法是什么?

时间:2008-09-16 10:38:03

标签: php mysql database pear

从PHP访问MySQL数据库时,似乎有几种方法:

Sprinkle the code with raw SQL-statements
Use the VO-pattern from Java (e.g. DB_DataObjects from PEAR)
DIY and write a script that auto-generates one PHP class per database 

除此之外,我还阅读了有关LINQ in .NET但未在PHP.中看到它的信息。

还有哪些其他模式?

如果您今天开始从头开始构建网站,您会选择哪一个?

澄清:这不是关于DB抽象层(PDO,MDB2)。这里讨论的模式是你在PDO或MDB2上构建的。

14 个答案:

答案 0 :(得分:6)

您正在寻找的是对象关系模型(ORM)。那里有几个不同的:

如果ORM对于您的项目来说太多了,那么您将回到像PDO这样的通用数据库接口并手动构建预准备语句。

答案 1 :(得分:5)

我从PEAR中选择MDB2 database abstraction layer - 它提供了一个很好的抽象方法来处理数据库。我推荐它,因为它允许你编写可移植的代码,可以移植到不同的数据库服务器而无需进行很多更改(对于基本脚本,只需更改连接调用就足够了)。它是旧DB和Metabase抽象层的合并(DB仍然支持错误修正,但已被MDB2取代)。

它为正确支持它的DB提供了准备+执行仿真等功能,并允许您使用占位符,这是避免SQL注入问题的好习惯。

它适用于:mysql / mysqli,pgsql(PostgreSQL),oci8(Oracle),sqllite,msql,mssql(Microsoft SQL Server),sybase,informix,fbsql,ibase,odbc。

查看MDB2 documentation,看看它是如何运作的。

答案 2 :(得分:2)

  

还有哪些其他模式?

ActiveRecord - 您可以在CakePHP中看到此示例。

我认为这在很大程度上取决于您的需求 - 如果您正在构建一个小型应用程序,那么构建DIY数据库层可能会更快。

如果您正在构建一个包含大量表和关系的大型应用程序,那么使用CakePHP的ActiveRecord功能可能会更快更容易。

我还没有使用过PEAR的抽象层,但它看起来也不错。 Zend还在Zend framework中有一个数据库库。

答案 3 :(得分:2)

这绝对取决于你写的网络应用程序有多大。我会为Doctrine添加我的大拇指(如果使用得当)。如果它是一个非常小的快速脏项目,你可能只是使用PDO

答案 4 :(得分:1)

“这取决于”

对于我自己的项目,我倾向于使用某种框架,其中包括一个抽象层。对于不适合框架的较小项目,我只是将SQL放在脚本中(因为它很小)。我最后一次没有框架的情况下做了一个相当大的应用程序,我使用PDO来获得简单的语句支持等等。这是一个非常容易学习的抽象层。如果我出于某种原因选择不使用框架,我可能会再次使用它。

答案 5 :(得分:1)

  

除此之外,我还阅读了.NET中的LINQ,但还没有看到它在PHP中实现。

像Linq这样的东西还不能在PHP中实现,因为该语言缺乏必要的结构。一种“假的linq”has been created,但这只是使用字符串而不是“真正的”linq。即使它是,它实际上只是Linq对象的等价物,并且没有像Linq到SQL的那样。

答案 6 :(得分:1)

如果你想要一种面向对象的方法,这就是我最近的方法。

我把事情分成两类,

首先,DatabaseTable类 - 获取一个表名,一个表是该表的键。其次,我创建了一个DatabaseObject类,它表示DatabaseTable中的一行。 DatabaseObject有两个例程setFromRow和getAsRow。 SetFromRow将从col =>值对的关联数组中设置对象,并且get as将基本上将对象序列化为col =>值对。

当在表上调用select方法时,DatabaseTable使用setFromRow来制作DatabaseObjects。相反,当告知更新或将数据插入其表时,DatabsaeTable将使用getAsRow序列化DatabaseObject。

通常会发生的事情是从DatabaseObject继承自己的特定对象,定义setFromRow和getAsRow,并告诉DatabaseTable要实例化的DatabaseObject的名称。

所以你最终写作,代码明智是这样的

$dbTable = new DatabaseTable('tableName', 'uniqueid', 'InstanceType')
// dbTable manufactures an InstanceType for our use based on the select below
$dbRow = $dbTable->selectUsingId(15); 
print_r($dbRow);  // Dumps the InstanceTypeObject

这将我的应用程序中的数据表示(DatabaseObject)与数据库表(DatabaseTable)的管理分开。所以我的DatabaseObject在C ++术语中可以是普通旧数据。

当然,你可以通过创建表之间的关系,创建更多的选择方法等来进一步发展。

我应该补充一点,将基本上是过程语言(SQL)与面向对象的内容集成起来并不容易,所以我的方法,我知道,有它的缺点,你可能会得到很多不同的答案自己的缺点。

答案 7 :(得分:1)

您可能还想考虑使用CodeIgniter,这是一个很好的PHP MVC框架。它具有ActiveRecord实现和一组合理的Database对象(包括绑定变量)。我发现它的DB类比默认的PHP MySQL API好得多,比PDO简单一点(当然更容易安装)。

答案 8 :(得分:0)

至少,使用PDO。它为大多数数据库平台提供了一个通用接口,如果您愿意,可以更轻松地切换数据库解决方案。

我喜欢使用对象关系映射器(ORM),例如propel:http://propel.phpdb.org/trac/

这会将您的对象直接映射到数据库模式 - 无需SQL。映射发生在XML文件中,通过Criteria对象进行查询。可以从数据库中反向设计PHP类,或者从模式xml生成数据库。

有关ORM的更多信息,请参阅http://en.wikipedia.org/wiki/Object-relational_mapping

答案 9 :(得分:0)

使用MVC结构和数据库抽象层。这样,您可以到一个地方完全重写数据访问类的内部,同时保持公共接口不变。

整个代码中的原始SQL几乎无法扩展。

答案 10 :(得分:0)

为了执行命令,我将使用常用SQL命令的函数。 然后可以使用这些函数来创建更具体的内容,如get_users()

a)为您可能想要进行的每个查询创建一个函数,例如 如

db_select($opts)

其中$ opts是带键的哈希数组:

['table_name', 'selection', 'condition', 'group_by', 'order_by', 'limit']

b)如果你大量使用SQL,我可能会想要创建一个SQL命令构建器,它接受一个哈希数组并返回一个命令。类似的东西:

db_builder(array('select'=>array('customers','from'=>'bar','where'=>'foo=10')))

上面提到的函数会在它们的实现中使用它,所以如果你需要一个完全随机的语句,你也希望通过在任何地方重用命令构建器代码来实现整个过程。

答案 11 :(得分:0)

我采用两级手动编码方法:

第一级是一组简单的函数:

  • do_query(sql):返回(打开)结果对象。
  • get_record(sql):返回第一条记录,查询关闭。
  • get_datum(sql):返回第一条记录的第一个字段(查询已关闭)

之后,我编写了我的模型层,其中包含了所有数据操作的特定功能。通常是一个文件,其中包含每个概念对象的部分。参数绑定到抽象数据,而不是SQL结构。所有SQL都在这一层。

答案 12 :(得分:0)

任何方式都是好的,只要您在数据库架构更改(输入,过滤,验证,表单生成等)时最小化需要更改代码的点。

我喜欢用 PDO 参数化SQL 来简化它们,它们抽象了返回的数据集(::getActiveUsers()::getUserPersonalData()等。)。

答案 13 :(得分:0)

您可以使用像Doctrine这样的ORM。