openSUSE15.3 apache無法解析php7的問題

開篇——這看起來是一個很簡單的問題,但又絕不同于以往的任何一個類似的問題,即便搜遍全網(wǎng),可能也找不到答案,但這篇會帶領(lǐng)您一窺究竟
  • 先按國際慣例,安裝好 apache2 和php7,以及 apache2-mod_php7
zypper install apache2
zypper install php7
//這時 apache2-mod_php7可能已經(jīng)自動安裝上了,如果沒裝,手動安裝一下就好
zypper install apache2-mod_php7
  • 查看 apache 配置文件中 web 目錄位置,然后新建 phpinfo.php
    openSUSE的 apache 的配置文件分得很散,一個配置文件可以搞定的事全部打散成各個小的配置文件位于 /etc/apache2 下,主配置文件是 /etc/apache2/httpd.conf,但是 web 目錄位置配置又在 /etc/apache2/default-server.conf 里,這種體驗(yàn)很不友好,尤其是對新手
DocumentRoot "/srv/www/htdocs"

我們在 /srv/www/htdocs 下新建一個 phpinfo.php文件

<?php
echo phpinfo();
?>
  • 好玩的來了,當(dāng)我打開瀏覽器訪問 localhost/phpinfo.php 的時候,瀏覽器怎么也解析不了php文件,始終提示我下載文件
    按理說,如果是 CentOS,到這一步PHP環(huán)境基本就已經(jīng)配置成功了
開始解決問題
  • 一開始我的直覺是沒有加載mod_php7模塊,后來證明也的確如此,于是乎我根據(jù) http.conf 的配置順藤摸瓜,發(fā)現(xiàn) openSUSE 的 apache 把模塊加載配置專門放到了一個 /etc/apache2/loadmodule.conf 文件里,我喜出望外,馬上加上
LoadModule php7_module                    /usr/lib64/apache2/mod_php7.so

然后重啟

service apache2 restart

呵呵,我還是太輕敵了,發(fā)現(xiàn)還是不行,但是詭異的是,明明執(zhí)行 httpd -M 可以看到加載了 mod_php7

httpd -M
....
reqtimeout_module (shared)
authn_core_module (shared)
authz_core_module (shared)
php7_module (shared)
  • 從錯誤日志入手
    打開 /var/log/apache2/error_log,發(fā)現(xiàn)大有乾坤
[Sat Jun 26 04:02:53.190028 2021] [core:notice] [pid 9492] AH00094: Command line: 
'/usr/sbin/httpd-prefork -D SYSCONFIG -C PidFile /var/run/httpd.pid -C 
Include /etc/apache2/sysconfig.d//loadmodule.conf -C 
Include /etc/apache2/sysconfig.d//global.conf -f /etc/apache2/httpd.conf -c 
Include /etc/apache2/sysconfig.d//include.conf -D SYSTEMD -D FOREGROUND'

這是怎么回事,怎么是 /etc/apache2/sysconfig.d//loadmodule.conf 這個模塊加載配置文件,不是 /etc/apache2/loadmodule.conf 這個嗎?

原來 service apache2 restart 這個服務(wù)啟動的配置和直接使用httpd命令執(zhí)行apache使用的配置不一樣,這就是為什么使用 httpd -M 可以看到加載了 mod_php7 模塊,但使用 service 啟動后瀏覽器卻無法解析

那么我在 /etc/apache2/sysconfig.d//loadmodule.conf 里加上 mod_php7 的配置不就可以了嗎,我再次喜出望外,當(dāng)我加上之后,再次啟動 apache ,發(fā)現(xiàn)這個 loadmodule.conf 居然又被重置了,也就是說,這個并不是一個真正的配置文件,而是通過其他的程序生成的一個緩存文件罷了

  • 再次順藤摸瓜
    需要找到這個 loadmodule.conf 是怎么生成的,先找到 service 啟動腳本所在 /usr/lib/systemd/system/apache2.service
//apache2.service的內(nèi)容
[Unit]
Description=The Apache Webserver
After=network.target nss-lookup.target time-sync.target remote-fs.target
Before=getty@tty1.service plymouth-quit.service xdm.service
PartOf=apache2.target

[Service]
Type=notify
PrivateTmp=true
ExecStart=/usr/sbin/start_apache2 -DSYSTEMD -DFOREGROUND -k start
ExecReload=/usr/sbin/start_apache2 -DSYSTEMD -DFOREGROUND -k graceful
ExecStop=/usr/sbin/start_apache2 -DSYSTEMD -DFOREGROUND -k graceful-stop
KillMode=mixed
TasksMax=infinity
NotifyAccess=all

[Install]
WantedBy=multi-user.target
Alias=httpd.service apache.service

原來真正的啟動腳本是 /usr/sbin/start_apache2 ,再次打開這個文件,在143行處可以看到調(diào)用了 get_module_list 這個函數(shù),但是這個函數(shù)的實(shí)現(xiàn)卻沒有在這個腳本里,肯定在某個引用腳本里

#!/bin/sh
#
# Copyright (c) 1996, 1997, 1998 S.u.S.E. GmbH
# Copyright (c) 1998, 1999, 2000, 2001 SuSE GmbH
# Copyright (c) 2002, 2003, (2004?) SuSE Linux AG
# Copyright (c) 2004(?), 2005, 2006, 2007, 2008 SUSE Linux Products GmbH
#
# Authors: Rolf Haberrecker <apache@suse.de>, 2001
#          Peter Poeml <apache@suse.de>, 2002, 2003, 2004, 2005, 2006, 2007, 
#                                        2008, 2009, 2010
#
#

.    /usr/share/apache2/script-helpers

看腳本開頭引入了 script-helpers 這么一個腳本,打開它

//大概64行處
function get_module_list
{
  load_sysconfig
  find_mpm

  for module in $APACHE_MODULES; do
      # special case
      # remove or add 'd' on in cgi module name
      case $module in mod_cgid|cgid) 
          case $HTTPD_MPM in prefork) module=${module%d};; esac;; 
      esac
      case $module in mod_cgi|cgi)   
          case $HTTPD_MPM in event|worker) module=${module}d;; esac;; 
      esac
      ......

果不其然,這個函數(shù)的實(shí)現(xiàn)在這里,根據(jù)代碼看得出是根據(jù) $APACHE_MODULES 這個變量循環(huán)得出最后要加載那些模塊,于是目光落在 $APACHE_MODULES 這個變量上,毫無疑問,這是個數(shù)組,而且也是通過某個配置文件讀取加載的,看到 get_module_list 函數(shù)第一行就調(diào)用了 load_sysconfig,沒錯就是它了,它的函數(shù)實(shí)現(xiàn)在 script-helpers 的開頭

#!/bin/bash

HTTPD_SBIN_BASE="/usr/sbin/httpd"

#
# loads sysconfig variables into environment
# 
# return value in: APACHE_*
#
function load_sysconfig
{
  [ -n "$sysconfig_loaded" ] && return
  [ ! -f "$SYSCONFIG_FILE" ] && return
  .  $SYSCONFIG_FILE
//在這里輸出 SYSCONFIG_FILE 的路徑
echo $SYSCONFIG_FILE
exit
  export ${!APACHE_*} sysconfig_loaded=true
}
.....

在 load_sysconfig 函數(shù)里打印 $SYSCONFIG_FILE 的值,然后停掉 apache2服務(wù),直接使用命令調(diào)用 apache2

service apache2 stop
/usr/sbin/start_apache2

最后輸出

/etc/sysconfig/apache2

哈哈,最后抽絲剝繭,終于發(fā)現(xiàn)它了,打開這個文件

# fairly minimal
# APACHE_MODULES="authz_host alias auth dir log_config mime setenvif"
#
# apache's default installation
# APACHE_MODULES="authz_host actions alias asis auth autoindex cgi dir imap include log_config mime negotiation setenvif status userdir"
# your settings
APACHE_MODULES="actions alias auth_basic authn_core authn_file authz_host authz_groupfile authz_core authz_user autoindex cgi dir env expires include log_config mime negotiation setenvif ssl socache_shmcb userdir reqtimeout"

在80行,APACHE_MODULES變量就位于此處,將 php7 加上,修改后

APACHE_MODULES="actions alias auth_basic authn_core authn_file authz_host authz_groupfile authz_core authz_user autoindex cgi dir env expires include log_config mime negotiation setenvif ssl socache_shmcb userdir reqtimeout php7"

再次重啟 apache 服務(wù)

service apache2 restart

終于看到了熟悉的 phpinfo 界面

  • openSUSE的開發(fā)環(huán)境體驗(yàn)還有待提升
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容