将PHP与数据库系统接口的PHP库实际上是如何调用数据库的



我一直在GitHub上查看Predis代码,它非常庞大,所以我很难从代码中找到答案,因为我不明白的每个文件夹/文件是什么

我想知道的是,当使用MySQL或Redis或任何其他数据库系统时,PHP实际上是如何联系数据库的?它是否使系统调用类似于用system("some command here");在C中进行的调用,或者开发人员是否必须实际扩展PHP语言的编译器才能做到这一点?

您不必"扩展编译器",但您必须做您可能想要做的事情:在C中编写一个PHP模块/扩展,与数据库的(通常)C库API对话。这是什么意思?数据库通常带有连接器库,这些连接器库通常用低级C编写,从而提供基于C的API。这或多或少类似于include 'api.php',它允许您调用刚才包含的任何函数,但它是特定于C的。PHP代码不能直接与C代码对话,但用C编写的PHP扩展可以充当PHP代码和C API之间的"桥梁"。

然后,C库可以选择如何与实际数据库对话。它可能会直接与数据库的另一个C API对话,尽管这并不一定是典型的。通常使用UNIX套接字或TCP套接字,如果数据库位于不同的计算机上,则有时会跨网络使用。如果愿意的话,可以直接从PHP代码中与UNIX/TCP套接字进行对话,但这意味着必须重新实现整个协议才能用PHP代码与数据库进行对话。这通常是低效的,因为PHP是一种相当高级的语言,并且不提供任何对原始计算机资源(如内存)的直接访问,这使得这种实现相当低效。

因此,它通常的做法是:

  • 数据库提供了一个协议,可以通过某种套接字与它进行通信
  • 官方协议客户端是在C库中实现的,因为它高效且可移植
  • 有人编写了一个PHP扩展,将C库API桥接到PHP用户代码中

没有什么可以阻止你在替代客户端中用其他语言实现该协议,但由于这通常是一个乏味的过程,而且C是一个广泛使用的系统,人们通常最终会围绕现有的官方C库编写包装器。

与各种数据库交互的函数/类由PHP扩展提供(就像PHP中的几乎所有东西一样),例如mysqli扩展。它们是Linux上的.so文件或Windows上的.dlls文件。或者,它们可以在构建时编译成PHP。无论哪种方式,它们都会调用Zend代码中的函数来注册将在PHP中调用的函数/类(例如mysqli_connect),并将它们连接到知道如何与数据库交互的代码中。PHP和扩展是用C编写的。如果你看看如何编写连接到MySQL的C代码的例子,那可能就是PHP中的mysqli/MySQL扩展所使用的。

最新更新