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

时间:2020-03-05 18:55:36  来源:igfitidea点击:

从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

除此之外,我还阅读了有关.NET中的LINQ的信息,但还没有看到它在PHP中的实现。
还有哪些其他模式?

如果我们今天开始从头开始构建网站,那么我们会选择哪个?

说明:这与数据库抽象层(PDO,MDB2)无关。这里讨论的模式是我们在PDO或者MDB2上构建的。

解决方案

回答

"这取决于"

对于我自己的项目,我倾向于使用某种框架,其中包括一个抽象层。对于不合适于框架的较小项目,我只是将SQL放在脚本中(因为它很小)。上一次我在没有框架的情况下执行大型应用程序时,我使用PDO来提供易于准备的语句支持等。这是一个易于学习的抽象层。如果由于某种原因我选择不使用框架,我可能会再次使用它。

回答

至少要使用PDO。它为大多数数据库平台提供了一个通用接口,使我们可以轻松切换数据库解决方案。

我喜欢使用像Proel这样的对象关系映射器(ORM):http://propel.phpdb.org/trac/

这将对象直接映射到不需要SQL的数据库模式。映射发生在XML文件中,查询通过Criteria对象发生。可以从数据库反向工程PHP类,或者从架构xml生成数据库。

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

回答

What other patterns are there?

ActiveRecord-我们可以在CakePHP中看到一个示例。

我认为,如果我们要构建一个小型应用程序,则它很大程度上取决于需求,这可能会更快地构建一个DIY数据库层。

如果我们要构建具有大量表和关系的大型应用程序,则使用CakePHP的ActiveRecord功能之类的方法可能会更快,更容易。

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

回答

使用MVC结构和数据库抽象层。这样一来,我们就可以在完全保持公共接口不变的情况下,完全修改数据访问类的内部结构。

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

回答

Apart from this I have also read about LINQ in .NET but have not seen it implemented in PHP.

像Linq这样的东西尚不能用PHP实现,因为该语言缺少必要的构造。已经创建了一种"假linq",但这仅使用字符串,而不是"真实" linq。即使是这样,它实际上也只是Linq与对象的对等,没有什么比Linq to SQL更好的了。

回答

我会从PEAR中选择MDB2数据库抽象层,它提供了一种很好的抽象方法来处理数据库。我建议这样做,因为它允许我们编写可移植的代码,而无需进行许多更改即可将它们移植到其他数据库服务器(对于基本脚本,只需更改connect调用就足够了)。它是旧数据库和元数据库抽象层的合并(错误修复仍支持数据库,但已被MDB2取代)。

它为不正确支持的数据库提供了诸如准备+执行仿真之类的功能,并允许我们使用占位符,这是避免SQL注入问题的好习惯。

它将与以下版本一起使用:mysql / mysqli,pgsql(PostgreSQL),oci8(Oracle),sqllite,msql,mssql(Microsoft SQL Server),sybase,informix,fbsql,ibase,odbc。

查看MDB2文档以了解其工作方式。

回答

为了执行命令,我将对常用的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')))

上面提到的函数将在其实现中使用此函数,如果我们需要一个完全随机的语句,也将使用它,希望通过在各处重用命令构建器代码,使整个过程变得牢不可破。

回答

我执行两级手工编码方法:

第一级是一组简单的功能:

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

之后,我编写我的模型层,并为所有数据操作提供特定功能。通常是单个文件,每个概念对象都有节。参数绑定到抽象数据,而不绑定到SQL结构。所有的SQL都在这一层。

回答

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

我将事情分为两类,

首先,DatabaseTable类采用一个表名,即该表的键的字符串。其次,我创建一个DatabaseObject类,该类代表DatabaseTable中的一行。 DatabaseObject具有两个例程setFromRow和getAsRow。 SetFromRow将通过col => value对的关联数组设置对象,并且get as row本质上会将对象序列化为col => value对。

在表上调用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)的管理分开。因此,用C ++术语来说,我的DatabaseObject可以是纯旧数据。

当然,通过创建表之间的关系以及创建更多选择方式等,我们可以走得更远。

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

回答

我们正在寻找的是对象关系模型(ORM)。有几个不同的地方:

  • 推进
  • 教义

如果ORM对于项目来说太多了,那么我们将退回到通用的DB接口(如PDO)并手动构建准备好的语句。

回答

我们可能还需要考虑使用CodeIgniter,这是一个不错的PHP MVC框架。它既有ActiveRecord实现,又有合理的数据库对象集(包括绑定变量)。我发现它的数据库类比默认的PHP MySQL API好得多,并且比PDO简单(肯定更容易安装)。

回答

只要将数据库架构更改(输入,过滤,验证,表单生成等)时需要更改代码的点减到最少,任何方法都是好的。

我想通过PDO,参数化SQL和抽象化返回的数据集的类(`:: getActiveUsers(),:: getUserPersonalData()等)来简化操作。

回答

阅读Lerdorf先生本人对PHP网站"添加结构"的看法。

www.oracle.com/technology/pub/articles/php_experts/rasmus_php.html

回答

这肯定取决于我们正在编写的Web应用程序的大小。我会赞成"教义"(如果使用得当的话)。如果这是一个很小的Quick-N-dirty项目,那么我们可能就可以摆脱使用PDO的麻烦了。