从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上构建的。
答案 0 :(得分:6)
答案 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)
答案 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)
我采用两级手动编码方法:
第一级是一组简单的函数:
之后,我编写了我的模型层,其中包含了所有数据操作的特定功能。通常是一个文件,其中包含每个概念对象的部分。参数绑定到抽象数据,而不是SQL结构。所有SQL都在这一层。
答案 12 :(得分:0)
任何方式都是好的,只要您在数据库架构更改(输入,过滤,验证,表单生成等)时最小化需要更改代码的点。
我喜欢用 PDO ,参数化SQL 和类来简化它们,它们抽象了返回的数据集(::getActiveUsers()
, ::getUserPersonalData()
等。)。
答案 13 :(得分:0)
您可以使用像Doctrine这样的ORM。