2011-11-15 28 views
7

Tôi có một kịch bản thử nghiệm rất đơn giản:Kết nối PDO hoạt động từ dòng lệnh, nhưng không phải thông qua 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"; 

} 

?> 

Khi tôi thực hiện kịch bản này từ dòng lệnh, nó hoạt động một cách hoàn hảo:

$ 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 

Nhưng khi tôi truy cập vào kịch bản chính xác tương tự thông qua trình duyệt web của tôi , nó nói:

Could not connect to database, rawr. :-(

tôi đã thử var_dump về lỗi, và thông điệp là: "SQLSTATE [HY000] [2003] không thể kết nối với máy chủ MySQL trên ' db.example.edu '(13) ".

Điều này thật khó hiểu. Đó là cùng một kịch bản chính xác trên cùng một máy chủ - tại sao nó hoạt động khi tôi thực thi nó từ dòng lệnh, nhưng thất bại khi Apache thực thi nó?

+0

Đây có phải là máy chủ Linux không? Có phải Red Hat hoặc CentOS đang chạy SELinux không? Nếu vậy, bạn có thể cần phải kích hoạt các booleans SELinux 'httpd_can_network_connect' và' httpd_can_network_connect_db' để cho phép Apache thiết lập các kết nối đến một máy chủ cơ sở dữ liệu từ xa. –

+1

thông tin thêm về lỗi này (13 = quyền bị từ chối) là ở đây: http://www.filonov.com/blog/2009/08/07/sqlstatehy000-2003-cant-connect-to-mysql-server-on-xxx -xxx-xxx-xxx-13/ – thetaiko

+0

@Michael Vâng, đó là một máy chủ RHEL 6.1, và một cái mới sáng bóng ở đó. Ngoài ra, @thetaiko - đã hoạt động! SELinux chặn kết nối và chạy 'setsebool -P httpd_can_network_connect = 1' làm gốc đã sửa nó. Nếu bạn muốn đăng bài đó như một câu trả lời, tôi sẽ vui vẻ chấp nhận và upvote. –

Trả lời

24

Nếu đây là bản phân phối có nguồn gốc từ Red Hat (RHEL, CentOS, Fedora, ScientificLinux) chạy SELinux (hoặc bất kỳ đạo hàm không Red Hat nào bằng SELinux), cài đặt chính sách mặc định tại thời điểm viết bài này. các kết nối bên ngoài tới các máy chủ hoặc cơ sở dữ liệu khác. Là root, bạn phải kích hoạt hai boolean SELinux sau đây. Sử dụng tùy chọn -P để duy trì thay đổi trong quá trình khởi động lại.

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

Lưu ý rằng httpd_can_network_connect có thể không cần thiết. Hãy thử nó trước tiên chỉ bật httpd_can_network_connect_db.

+2

Cảm ơn! Dòng 'httpd_can_network_connect' không cần thiết trong trường hợp của tôi, chỉ là dòng' httpd_can_network_connect_db'. –

+0

Bạn đã lưu ngày của tôi. Cảm ơn rất nhiều ◕‿◕ – PHPst

+0

nếu bạn chưa bỏ phiếu này, hãy làm như vậy ... – bart2puck

0

tôi đã cùng một vấn đề cho PHP ftp ftp_connect và phải thiết lập các

setsebool -P httpd_can_network_connect=1 

Đó là bối rối vì những thứ khác như fil_get_contents và làm việc curl qua PHP và apache tốt trước khi thiết lập đó.

-1

Cùng một vấn đề nhưng nguyên nhân khác nhau ở đây
giải pháp tôi chỉ là một đơn giản apt-get install php-mysql đi

Hãy chắc chắn để séc pdo_mysql trong phpinfo() của bạn
Tìm thấy nó về bài đăng này: PDOException “could not find driver”

Tôi tự hỏi tại sao CLI làm việc trong điều kiện như vậy O_o Có thể có thứ gì đó được cài đặt không chính xác, hoặc bị quá tải? Vâng, bây giờ, nó hoạt động tốt!

+0

Bạn có thể giải thích thay vì chỉ giảm giá? Tôi vẫn không biết tại sao nó lại hoạt động trong CLI chứ không phải thông qua Apache. Nếu tôi bỏ lỡ một cái gì đó hiển nhiên, xin vui lòng, chỉ cần cho chúng tôi biết GÌ. Tôi đã đăng giải pháp của mình vì nó * thực sự đã giải quyết được sự cố của tôi * và có thể giúp người khác. Nếu tôi làm điều gì đó hoàn toàn sai, hãy làm chúng tôi vui lòng. – Balmipour

0

Bên cạnh đó bằng cách sử dụng các câu trả lời được chấp nhận trên

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

tôi cũng đã thay đổi bối cảnh an ninh của một tập tin mà httpd đang cố gắng truy cập.

Tập lệnh php chạy qua apache đang cố truy cập tệp chứng chỉ nằm ngoài gốc tài liệu bình thường của httpd. Việc thay đổi quyền truy cập tệp để cho phép truy cập httpd là không đủ để cho phép truy cập httpd vào tệp đó.Tôi đã phải thay đổi để bối cảnh an ninh tốt, vì vậy trước khi thay đổi:

[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 

Thay đổi bối cảnh sử dụng:

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

để có được:

[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 

Bây giờ tất cả là tốt. Một nguồn tài nguyên tốt để xem là /var/log/audit/audit.log và chú ý đến các lỗi. Trong trường hợp của tôi, lỗi chỉ đến hướng của độ phân giải là:

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 
Các vấn đề liên quan