官方PHP:Apache Docker镜像-让MySql插件工作起来



我使用的是官方的docker php:apache镜像,但我不能将mysqli与php一起使用
我得到了"Class";mysqli"找不到'每当我尝试这个:

$conn = new mysqli($servername, $username, $password, $dbname);

我看到到处都有很多关于在dockerfile中添加mysqli安装的内容。我真的不确定这是否有必要,原因有几个:

当我在容器上打开bash时,我看到mysqlnd是作为php模块安装的。

以下是我的docker-compose.yml:中的片段

lamp-www:
depends_on:
- db
image: php:apache
volumes:
- "./www:/var/www/html"
ports:
- 8080:80

当我做PhpInfo()时,我看到"--启用mysqlnd";我看到了一个mysqlnd部分
声明版本名称:"mysqlnd 8.0.10";。

我没有看到任何迹象表明旧的mysqli和mysqlnd之间的语法不同,这表明它是相同的。我试过用";mysqlnd";以及";mysql";但是它们都产生与"错误"相同的错误;mysqli";。

我也没有看到任何迹象表明你可以在使用"DockerFile"时使用DockerFile;图片:php:apache";。我也不想进入我的容器来安装或更改东西,然后重新提交,我想使用官方图片。

当我使用";图像";我的docker-compose.yml中的参数
有没有更干净的方法可以做到这一点,比如在我的compose中添加一个参数,安装我缺少的任何神秘东西?

最后一个问题:这是php的官方镜像,安装的模块似乎表明php支持mysql。我只是在尝试使用不推荐使用的函数/类吗?如果是,我应该使用什么?

根据这里的文档,它说:

什么不是

尽管MySQL Native Driver是作为PHP扩展编写的,但它需要注意的是,它没有为PHP提供新的API程序员MySQL数据库连接的程序员API是由MySQL扩展、mysqli和PDO MySQL提供。这些扩展现在可以使用MySQL Native Driver的服务与MySQL Server通信。因此,你不应该想到MySQL本机驱动程序作为API。

基本上,mysqlnd位于mysqlipdo_mysql下面的层中,它不会在PHP中添加函数/类,以便连接到MySql数据库。

这可以通过运行几个命令来检查(我假设是Linux或WSL的风格):

docker pull php:apache                 #downloading the official image
docker run --rm -it php:apache bash    #and running it in a temporal container

一旦进入集装箱:

php -m     #checking the modules for php
php -a     #executing a php interactive console

(请注意,在php -m的输出中,存在mysqlnd,但不存在mysqlipdo_mysql)
然后,在php控制台中运行以下行:

$conn = new mysqli('localhost', 'root', 'pass', 'db');              //connecting to a MySql db with mysqli
$dbh = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass'); //and the same with pdo_mysql

两行都将抛出错误:

Warning: Uncaught Error: Class "mysqli" not found in php shell code:1     //mysqli
Warning: Uncaught PDOException: could not find driver in php shell code:1 //pdo_mysql

即使在php的标准安装中,默认情况下也不会捆绑mysqli和pdo_mysql,因为你可能想使用其他数据库(PostgreSQL、SQLite、Oracle等),或者根本不使用,所以你需要为你的数据库安装特定的驱动程序。

使用Dockerfile安装MySQL驱动程序

Q: 您应该使用哪一个,mysqli还是pdo_mysql?

A: 不,我不会碰这个,选择你个人感觉最舒服的那个。这个问题与";选项卡还是空格&"vi,vim还是emacs&"披萨上的菠萝&"罗斯和瑞秋在休息吗"或";连衣裙是蓝色和黑色的还是白色和金色的"就分歧而言,两者都有优缺点,没有错误的答案(除非你把菠萝放在披萨上,说真的,你怎么了?)。

要安装任何一个或两个驱动程序,您需要创建一个Dockerfile,该文件使用php和准备使用的驱动程序创建一个新映像。你不需要从头开始,也不需要每次运行时都进入容器,因为你可以将你的图像建立在官方图像的基础上并进行扩展。

官方图片的自述文件中有这样做的说明,其中提到了图片中的helper命令,但我已经做了跑腿的工作:

#this uses the official image as a starting point
FROM php:apache
#humblebrag
MAINTAINER gorchestopher-h
#install both modules from source, you can delete the one you aren't using
RUN docker-php-ext-install mysqli pdo_mysql

就是这样!现在您有一个Dockerfile,需要保存在名为Dockerfile(无扩展名)的文件中,最好保存在docker-compose.yml文件旁边的目录中。

既然您有了这个文件,您就可以执行docker build命令并创建它,但由于您使用的是docker compose,您在自动化方面已经领先了几步,所以您只需要编辑您的compose文件,第一次使用新配置运行docker-compose up时,它就会为您完成任务。

但问题是,image密钥的工作方式是:

如果图像不存在,Compose会尝试提取它,除非您还指定了build,在这种情况下,它使用指定的选项,并使用指定的标记对其进行标记。

因此,这意味着我们可以在compose文件中设置build密钥来构建Dockerfile但是它需要有一个唯一的名称,这样它就不会与系统和官方存储库中已经存在的php:apache映像混淆。

这可以使用图像和构建密钥来完成:

lamp-www:
depends_on:
- db 
image: gorchestopher-h/php-mysql:apache           #the resulting image gets named this
build: ./name-of-the-directory-next-to-the-yml    #where to find the Dockerfile file
volumes:
- "./www:/var/www/html"
ports:
- 8080:80

就是这样,现在第一次docker-compose up这个合成文件时,由于找不到图像,所以会构建图像,如果修改Dockerfile并再次旋转它。它什么也不做,因为映像已经存在,你需要执行docker-compose build lamp-www(服务的名称是可选的,如果你跳过它,它会构建每个build密钥)来重新创建它,并且在你旋转新映像以释放未使用的旧映像后执行docker image prune

要检查是否一切顺利,可以重复以前的命令。

docker run --rm -it gorchestopher-h/php-mysql:apache bash #run the container with the awesome new name

在集装箱内,你可以运行

php -m #check the installed modules, it should have mysqli and/or pdo_mysql
php -a #executes a php terminal

在php终端上,您可以再次测试连接

$conn = new mysqli('localhost', 'root', 'pass', 'db');              //connecting to a MySql db with mysqli
$dbh = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass'); //and the same with pdo_mysql

最新更新