2011-11-15 88 views
7

我有一個非常簡單的測試腳本:PDO連接從命令行運行,但不通過Apache?

<?php 

$DSN = "mysql:host=db.example.edu;port=3306;dbname=search_data"; 

try { 

    $DB = new PDO($DSN, "username", "super-secret-password!"); 

} catch (PDOException $e) { 

    header('Content-Type: text/plain'); 
    print "Could not connect to database, rawr. :-("; 
    exit; 

} 


$SQL = "SELECT phrase FROM search ORDER BY RAND() LIMIT 10"; 

foreach($DB->query($SQL) as $row){ 

    print $row['phrase']."\n"; 

} 

?> 

當我執行命令行這個腳本,它完美的作品:

$ php test.php 
corporal punishment 
Stretches 
voluntary agencies and the resettlement of refugees 
music and learning 
Nike Tiger Woods Scandal 
Hermeneia 
PSYCHINFO 
anthony bourdain 
Black-White Couples and their Social Worlds 
colonization, hodge 

但是當我通過網絡瀏覽器訪問完全相同的腳本,它說:

Could not connect to database, rawr. :-(

我的錯誤嘗試var_dump,消息是:「SQLSTATE [HY000] [2003]無法連接到MySQL服務器' db.example.edu'(13)「。

這是令人費解的。它是完全相同的服務器上的完全相同的腳本 - 爲什麼當我從命令行執行它時會工作,但在Apache執行它時會失敗?

+0

這是Linux服務器嗎?運行SELinux的是Red Hat還是CentOS?如果是這樣,您可能需要啓用SELinux布爾型'httpd_can_network_connect'和'httpd_can_network_connect_db'以允許Apache建立到遠程數據庫主機的連接。 –

+1

有關此錯誤的更多信息(13 =權限被拒絕)在此處:http://www.filonov.com/blog/2009/08/07/sqlstatehy000-2003-cant-connect-to-mysql-server-on-xxx -xxx-xxx-xxx-13/ – thetaiko

+0

@Michael是的,它是一個RHEL 6.1服務器,並且是一個閃亮的新服務器。另外,@thetaiko - 工作!這是SELinux阻止連接,並以root身份運行'setsebool -P httpd_can_network_connect = 1'來修復它。如果你想發佈這個答案,我會很樂意接受和贊成。 –

回答

24

如果這是運行SELinux(或任何非使用SELinux的紅帽衍生產品)的Red Hat衍生髮行版(RHEL,CentOS,Fedora,ScientificLinux),則本文寫作時的默認策略設置是禁止Apache與其他服務器或數據庫的外部連接。作爲root用戶,您必須啓用以下兩個SELinux布爾值。使用-P選項可在重新啓動時保留更改。

setsebool -P httpd_can_network_connect=1 
setsebool -P httpd_can_network_connect_db=1 

請注意,httpd_can_network_connect可能沒有必要。首先嚐試使用httpd_can_network_connect_db

+2

謝謝!在我的情況下,'httpd_can_network_connect'這一行不是必需的,只是'httpd_can_network_connect_db'行。 –

+0

你救了我的一天。非常感謝◕‿◕ – PHPst

+0

如果您還沒有投票贊成,請這樣做... – bart2puck

0

我對PHP FTP FTP_CONNECT同樣的問題,不得不設置

setsebool -P httpd_can_network_connect=1 

這是令人困惑,因爲其他像fil_get_contents並通過PHP和Apache設置,以前就好了捲曲的工作。

-1

同樣的問題,但不同的原因在這裏
解決方案僅僅是一個簡單的apt-get install php-mysql

一定要檢查PDO_MYSQL在你的phpinfo()
發現它這個帖子:PDOException 「could not find driver」

不知O_O也許一些安裝不正確,或得到了重寫在這種條件下爲什麼CLI工作?那麼,現在,它工作正常!

+0

注意解釋而不是僅僅downvoting?我仍然不知道它爲什麼在CLI中起作用,而不是通過Apache。如果我錯過了明顯的東西,請告訴我們什麼。 我發佈了我的解決方案,因爲它*實際上解決了我的問題*,並可能幫助其他人。如果我做了完全錯誤的事情,請讓我們高興。 – Balmipour

0

另外,使用上述接受的答案

setsebool -P httpd_can_network_connect=1 
setsebool -P httpd_can_network_connect_db=1 

我不得不也改變httpd試圖訪問一個文件的安全上下文。

通過Apache運行PHP腳本試圖訪問是的httpd正常的文檔根目錄之外的證書文件。更改文件權限以允許httpd訪問不足以允許httpd訪問該文件。我不得不改變與安全上下文一樣,所以之前的變化:

[admin]$ ls -Z ../../certs/rds-ca-2015-root-us-east-1-BUNDLE.pem 
-rw-r--r--. admin apache unconfined_u:object_r:unlabeled_t:s0 ../../certs/rds-ca-2015-root-us-east-1-BUNDLE.pem 

變化環境中使用:

sudo chcon -v --type=httpd_sys_content_t ../../certs/rds-ca-2015-root-us-east-1-BUNDLE.pem``` 

獲得:

[admin]$ ls -Z ../../certs/rds-ca-2015-root-us-east-1-BUNDLE.pem 
-rw-r--r--. admin apache unconfined_u:object_r:httpd_sys_content_t:s0 ../../certs/rds-ca-2015-root-us-east-1-BUNDLE.pem 

現在一切都很好。一個好的資源是/var/log/audit/audit.log,並密切關注錯誤。在我的情況下,指向分辨率方向的錯誤是:

type=AVC msg=audit(1509047616.042:4049): avc: denied { read } for pid=17096 comm="httpd" name="rds-ca-2015-root-us-east-1-BUNDLE.pem" dev="xvdb" ino=262146 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:unlabeled_t:s0 tclass=file 
相關問題