PHP 7.0 下安裝 phpLDAPadmin 發生錯誤的修正方法

在稍具規模的網路環境中, 網管時常選用 LDAP 來進行帳號的統整管理, 一方面提供管理便利度, 另一方面使用者也不必因為不同系統而記憶不同帳號, phpLDAPadmin 是一套常見的 LDAP 管理介面, 但 phpLDAPadmin 已經很久沒有更新了, 若想要安裝在 PHP 5.6 以上, 甚至是最新版的 PHP 7 的環境中, 是無法順利安裝的, 因此我們需要做些修正.

Session 相關錯誤

打開 index.php 時出現下列錯誤:

  • Undefined variable: _SESSION in …. on line 379
  • Fatal error: Uncaught Error: Call to a member function getValue() on null in … on line 379

導致這個錯誤的主要原因是因為 phpLDAPadmin 需要使用 session, 在 PHP 中若要使用 session, 需要先執行 session_start() 這個函數, 但不知道為什麼 phpLDAPadmin 並沒有這麼做, 因此要解決這個問題, 一種方法是自己找正確的地方加上 session_start(), 另一種方法則是啟動 auto_start 這個特性, 這邊介紹如何啟動 auto_start 這個特性

編輯 php.ini 中的 session.auto_start

session.auto_start = 0

修改為

session.auto_start = 1

password_hash 相關錯誤

修正完 session 的問題後, 畫面上還有一個關於 password_hash 的錯誤

  • Fatal error: Cannot redeclare password_hash() in … on line 2236

造成這個錯誤的原因在於 php 5.5 以後內建了 password_hash 這個函數, 導致內建的 password_hash 與 phpLDAPadmin 自己的 password_hash 發生衝突, 因此只要將 phpLDAPadmin 的 password_hash 名稱替換成別的名稱就可以避開這個問題了

具體的解決辦法如下

對檔案打 patch

wget https://raw.githubusercontent.com/osixia/docker-phpLDAPadmin/stable/image/service/phpldapadmin/assets/php5.5.patch
patch -p1 -d ./phpldapadmin < php5.5.patch

修改 TemplateRender.php

sed -i "s/password_hash/password_hash_custom/g" ./phpldapadmin/lib/TemplateRender.php

Mac 的使用者會遇到 invalid command code W 這個錯誤, 具體原因與解決辦法請參考 MAC 下執行 sed 指令出現錯誤: invalid command code W

記得把指令中的 ./phpldapadmin 替換成 phpldapadmin 的實際位置

MAC 下執行 sed 指令出現錯誤: invalid command code W

sed 是 Linux/Mac 下非常好用的文件內容替換工具, sed -i "s/old/new/g" /path/to/file 可以讓我們輕鬆的將 /path/to/file 中的 old 都替換成 new, 但最近發現 sed 在 mac 與 Linux 上的行為有些許不同, 本來在 Linux 上能夠正常運作的指令在 MAC 上卻無法運作, sed 執行時出現錯誤 invalid command code W

MAC 上的 sed 手冊對於 -i 的描述:

-i extension
    Edit files in-place, saving backups with the specified extension.  If a zero-length extension is given, no backup will be saved.  It is not recommended to give a zero-
    length extension when in-place editing files, as you risk corruption or partial content in situations where disk space is exhausted, etc.

而 Linux 上的 sed 手冊對於 -i 的描述:

-i[SUFFIX], --in-place[=SUFFIX]
    edit files in place (makes backup if SUFFIX supplied)

根據手冊的中的描述, sed 在帶有 -i 參數時, 會針對處理的檔案進行備份, 而 -i 參數接受一個字串作為備份檔案的後綴( ex: test.php => test_ext.php ), 這個後綴在 Linux 下是可選, Mac 下是必要的, 雖然 Mac 下的 sed 可以給空字串來忽略這個選項, 但備份很重要, 備份一下啦!!

在知道差異後, 我們只要將後綴加上去就可以解決這個問題了!

Linux:
sed -i "s/old/new/g" /path/to/file

Mac:
sed -i "" "s/old/new/g" /path/to/file