Tham khảo - Lỗi này có nghĩa là gì trong PHP?
Cái này là cái gì?
Đây là một số câu trả lời về các cảnh báo, lỗi và thông báo mà bạn có thể gặp phải khi lập trình PHP và không biết cách khắc phục chúng. Đây cũng là một Wiki cộng đồng, vì vậy mọi người được mời tham gia thêm và duy trì danh sách này.
Tại sao thế này?
Các câu hỏi như "Tiêu đề đã được gửi" hoặc "Gọi một thành viên không phải đối tượng" thường xuyên xuất hiện trên Stack Overflow. Nguyên nhân sâu xa của những câu hỏi đó luôn giống nhau. Vì vậy, câu trả lời cho những câu hỏi đó thường lặp lại chúng và sau đó hiển thị OP nên thay đổi dòng nào trong trường hợp cụ thể của chúng. Những câu trả lời này không thêm bất kỳ giá trị nào cho trang web vì chúng chỉ áp dụng cho mã cụ thể của OP. Những người dùng khác gặp phải lỗi tương tự không thể dễ dàng đọc được giải pháp vì chúng đã được bản địa hóa quá nhiều. Điều đó thật đáng buồn vì một khi bạn đã hiểu được nguyên nhân gốc rễ thì việc sửa lỗi là chuyện nhỏ. Do đó, danh sách này cố gắng giải thích giải pháp một cách chung chung để áp dụng.
Tôi nên làm gì ở đây?
Nếu câu hỏi của bạn bị đánh dấu là trùng lặp với câu hỏi này, vui lòng tìm thông báo lỗi của bạn bên dưới và áp dụng bản sửa lỗi cho mã của bạn. Các câu trả lời thường chứa các liên kết khác để điều tra trong trường hợp không nên rõ ràng chỉ từ câu trả lời chung chung.
Nếu bạn muốn đóng góp, vui lòng thêm thông báo lỗi, cảnh báo hoặc thông báo "yêu thích" của bạn, mỗi câu trả lời, một mô tả ngắn ý nghĩa của nó (ngay cả khi nó chỉ làm nổi bật các thuật ngữ vào trang hướng dẫn của họ), một giải pháp khả thi hoặc cách tiếp cận gỡ lỗi và danh sách các câu hỏi và câu trả lời hiện có có giá trị. Ngoài ra, hãy cải thiện bất kỳ câu trả lời hiện có nào.
Danh sách
- Không có gì được nhìn thấy. Trang này trống và trắng. (còn được gọi là Trang trắng / Màn hình chết chóc )
- Mã không chạy / có vẻ như các phần trong mã PHP của tôi được xuất ra
- Cảnh báo: Không thể sửa đổi thông tin tiêu đề - tiêu đề đã được gửi
- Cảnh báo: mysql_fetch_array () yêu cầu tham số 1 là tài nguyên, boolean được cung cấp aka
Cảnh báo: mysql_fetch_array (): đối số được cung cấp không phải là tài nguyên kết quả MySQL hợp lệ aka
Cảnh báo: mysqli_num_rows () mong đợi tham số 1 là mysqli_result, boolean được cung cấp (hoặc các biến thể tương tự) - Cảnh báo: [function] yêu cầu tham số 1 là tài nguyên, boolean đã cho
- Cảnh báo: [function] : không mở được luồng: [lý do]
- Cảnh báo: hạn chế open_basedir có hiệu lực
- Cảnh báo: Chia cho 0
- Cảnh báo: Phần bù chuỗi bất hợp pháp 'XXX'
- Cảnh báo: count (): Tham số phải là một mảng hoặc một đối tượng triển khai Countable
- Lỗi phân tích cú pháp: lỗi cú pháp, không mong muốn '['
- Lỗi phân tích cú pháp: lỗi cú pháp, T_XXX không mong muốn
- Lỗi phân tích cú pháp: lỗi cú pháp, T_ENCAPSED_AND_WHITESPACE không mong muốn
- Lỗi phân tích cú pháp: lỗi cú pháp, T_PAAMAYIM_NEKUDOTAYIM không mong muốn
- Lỗi phân tích cú pháp: lỗi cú pháp, không mong đợi 'request_once' (T_REQUIRE_ONCE), mong đợi hàm (T_FUNCTION)
- Lỗi phân tích cú pháp: lỗi cú pháp, T_VARIABLE không mong muốn
- Lỗi nghiêm trọng: Đã hết kích thước bộ nhớ được phép là XXX byte (đã cố gắng phân bổ XXX byte)
- Lỗi nghiêm trọng: Gọi đến một hàm thành viên ... trên một đối tượng không phải hoặc null
- Lỗi nghiêm trọng: Gọi đến chức năng không xác định XXX
- Lỗi nghiêm trọng: Không thể khai báo lại XXX
- Lỗi nghiêm trọng: Không thể sử dụng giá trị trả về của hàm trong ngữ cảnh ghi
- Lỗi nghiêm trọng: Khai báo AAA :: BBB () phải tương thích với CCC :: BBB () '
- Lỗi nghiêm trọng: Sử dụng $ this khi không ở trong ngữ cảnh đối tượng
- Lỗi nghiêm trọng: Không thể chuyển đổi đối tượng của Class Closure thành chuỗi
- Lỗi nghiêm trọng: Hằng số lớp không xác định
- Lưu ý: Chuyển đổi mảng thành chuỗi
- Lưu ý: Cố gắng lấy thuộc tính của lỗi không phải đối tượng
- Lưu ý: Biến hoặc thuộc tính không xác định
- Chú ý: Chỉ mục không xác định
- Lưu ý: Phần bù không xác định XXX [Tham khảo]
- Lưu ý: Độ lệch chuỗi chưa được khởi tạo: XXX
- Lưu ý: Sử dụng hằng số không xác định XXX - giả định là 'XXX'
- MySQL: Bạn có lỗi trong cú pháp SQL của mình; kiểm tra hướng dẫn sử dụng tương ứng với phiên bản máy chủ MySQL của bạn để biết cú pháp phù hợp để sử dụng gần ... tại dòng ...
- Tiêu chuẩn nghiêm ngặt: Phương thức non-static [<class> :: <method>] không được gọi là static
- Cảnh báo: hàm yêu cầu tham số X là boolean / string / integer
- Lỗi HTTP 500 - Lỗi máy chủ nội bộ
- Không được dùng nữa: Cú pháp truy cập bù đắp mảng và chuỗi có dấu ngoặc nhọn không được dùng nữa
Cũng thấy:
Trả lời
Cảnh báo: Không thể sửa đổi thông tin tiêu đề - tiêu đề đã được gửi
Xảy ra khi tập lệnh của bạn cố gắng gửi tiêu đề HTTP đến máy khách nhưng trước đó đã có đầu ra, dẫn đến tiêu đề đã được gửi tới máy khách.
Đây là một E_WARNING
và nó sẽ không dừng tập lệnh.
Một ví dụ điển hình sẽ là một tệp mẫu như thế này:
<html>
<?php session_start(); ?>
<head><title>My Page</title>
</html>
...
Các session_start()
chức năng sẽ cố gắng gửi header với cookie phiên cho khách hàng. Nhưng PHP đã gửi tiêu đề khi nó ghi <html>
phần tử vào luồng đầu ra. Bạn sẽ phải di chuyển session_start()
lên trên cùng.
Bạn có thể giải quyết vấn đề này bằng cách xem qua các dòng trước khi mã kích hoạt Cảnh báo và kiểm tra nơi nó xuất ra. Di chuyển bất kỳ mã gửi tiêu đề nào trước mã đó.
Một đầu ra thường bị bỏ qua là các dòng mới sau khi PHP đóng ?>
. Nó được coi là một thông lệ tiêu chuẩn để bỏ qua ?>
khi nó là điều cuối cùng trong hồ sơ. Tương tự như vậy, một nguyên nhân phổ biến khác cho cảnh báo này là khi phần mở đầu <?php
có khoảng trống, dòng hoặc ký tự ẩn trước nó, khiến máy chủ web gửi tiêu đề và khoảng trắng / dòng mới do đó khi PHP bắt đầu phân tích cú pháp sẽ không thể gửi. bất kỳ tiêu đề nào.
Nếu tệp của bạn có nhiều hơn một <?php ... ?>
khối mã trong đó, bạn không nên có bất kỳ khoảng trắng nào ở giữa chúng. (Lưu ý: Bạn có thể có nhiều khối nếu bạn có mã được tạo tự động)
Ngoài ra, hãy đảm bảo rằng bạn không có bất kỳ Dấu thứ tự Byte nào trong mã của mình, ví dụ: khi mã hóa của tập lệnh là UTF-8 với BOM.
Câu hỏi liên quan:
Lỗi nghiêm trọng: Gọi đến một hàm thành viên ... trên một đối tượng không phải
Xảy ra với mã tương tự như xyz->method()
nơi xyz
không phải là một đối tượng và do đó method
không thể được gọi.
Đây là một lỗi nghiêm trọng sẽ dừng tập lệnh (thông báo về khả năng tương thích chuyển tiếp: Nó sẽ trở thành lỗi có thể sửa được bắt đầu với PHP 7).
Thông thường đây là dấu hiệu cho thấy mã thiếu kiểm tra các điều kiện lỗi. Xác thực rằng một đối tượng thực sự là một đối tượng trước khi gọi các phương thức của nó.
Một ví dụ điển hình sẽ là
// ... some code using PDO
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);
Trong ví dụ trên, không thể chuẩn bị truy vấn và prepare()
sẽ gán false
cho $statement
. Việc cố gắng gọi execute()
phương thức sau đó sẽ dẫn đến Lỗi nghiêm trọng vì false
là "không phải đối tượng" vì giá trị là boolean.
Tìm hiểu lý do tại sao hàm của bạn trả về một boolean thay vì một đối tượng. Ví dụ, kiểm tra $pdo
đối tượng cho lỗi cuối cùng đã xảy ra. Chi tiết về cách gỡ lỗi này sẽ phụ thuộc vào cách xử lý lỗi đối với hàm / đối tượng / lớp cụ thể được đề cập.
Nếu thậm chí ->prepare
không thành công thì $pdo
đối tượng xử lý cơ sở dữ liệu của bạn không được chuyển vào phạm vi hiện tại . Tìm nơi nó được xác định. Sau đó, chuyển nó dưới dạng một tham số, lưu trữ nó dưới dạng thuộc tính hoặc chia sẻ nó qua phạm vi toàn cầu.
Một vấn đề khác có thể là tạo một đối tượng có điều kiện và sau đó cố gắng gọi một phương thức bên ngoài khối điều kiện đó. Ví dụ
if ($someCondition) {
$myObj = new MyObj();
}
// ...
$myObj->someMethod();
Bằng cách cố gắng thực thi phương thức bên ngoài khối điều kiện, đối tượng của bạn có thể không được xác định.
Câu hỏi liên quan:
Không có gì được nhìn thấy. Trang này trống và trắng.
Còn được gọi là Trang trắng của cái chết hoặc Màn trắng của cái chết . Điều này xảy ra khi báo cáo lỗi bị tắt và xảy ra lỗi nghiêm trọng (thường là lỗi cú pháp).
Nếu bạn đã bật ghi nhật ký lỗi, bạn sẽ tìm thấy thông báo lỗi cụ thể trong nhật ký lỗi của mình. Điều này thường nằm trong tệp có tên "php_errors.log", ở vị trí trung tâm (ví dụ: /var/log/apache2
trên nhiều môi trường Linux) hoặc trong thư mục của chính tập lệnh (đôi khi được sử dụng trong môi trường lưu trữ chia sẻ).
Đôi khi có thể đơn giản hơn nếu tạm thời cho phép hiển thị lỗi. Trang trắng sau đó sẽ hiển thị thông báo lỗi. Hãy cẩn thận vì những lỗi này có thể nhìn thấy cho mọi người truy cập trang web.
Điều này có thể dễ dàng thực hiện bằng cách thêm vào đầu script đoạn mã PHP sau:
ini_set('display_errors', 1); error_reporting(~0);
Mã sẽ bật hiển thị lỗi và thiết lập báo cáo ở mức cao nhất.
Vì lệnh ini_set()
được thực thi trong thời gian chạy nên nó không có tác dụng đối với lỗi phân tích cú pháp / cú pháp. Những lỗi đó sẽ xuất hiện trong nhật ký. Nếu bạn muốn hiển thị chúng trong đầu ra (ví dụ như trong trình duyệt), bạn phải đặt display_startup_errors
chỉ thị thành true
. Thực hiện điều này trong php.ini
hoặc trong a .htaccess
hoặc bằng bất kỳ phương pháp nào khác ảnh hưởng đến cấu hình trước thời gian chạy .
Bạn có thể sử dụng các phương pháp tương tự để đặt chỉ thị log_errors và error_log để chọn vị trí tệp nhật ký của riêng bạn.
Nhìn vào nhật ký hoặc sử dụng màn hình, bạn sẽ nhận được thông báo lỗi tốt hơn nhiều và dòng mã nơi tập lệnh của bạn dừng lại.
Câu hỏi liên quan:
- Màn hình trắng chết chóc của PHP
- Màn hình trắng của cái chết!
- PHP không hiển thị thông báo lỗi
- PHP phát ra lỗi 500 - điều này được ghi lại ở đâu?
- Làm thế nào để nhận được thông báo lỗi hữu ích trong PHP?
- Tất cả các câu hỏi về "Trang trắng của cái chết" PHP trên Stackoverflow
Các lỗi liên quan:
Chú ý: Chỉ mục không xác định
Xảy ra khi bạn cố gắng truy cập vào một mảng bằng một khóa không tồn tại trong mảng.
Ví dụ điển hình của một Undefined Index
thông báo sẽ là ( demo )
$data = array('foo' => '42', 'bar');
echo $data['spinach'];
echo $data[1];
Cả hai spinach
và 1
không tồn tại trong mảng, gây ra một E_NOTICE
được kích hoạt.
Giải pháp là đảm bảo chỉ mục hoặc bù đắp tồn tại trước khi truy cập chỉ mục đó. Điều này có thể có nghĩa là bạn cần phải sửa một lỗi trong chương trình của mình để đảm bảo rằng các chỉ mục đó tồn tại khi bạn mong đợi. Hoặc nó có thể có nghĩa là bạn cần kiểm tra xem các chỉ mục có tồn tại bằng cách sử dụng array_key_exists
hoặc isset
:
$data = array('foo' => '42', 'bar');
if (array_key_exists('spinach', $data)) {
echo $data['spinach'];
}
else {
echo 'No key spinach in the array';
}
Nếu bạn có mã như:
<?php echo $_POST['message']; ?>
<form method="post" action="">
<input type="text" name="message">
...
sau đó $_POST['message']
sẽ không được đặt khi trang này được tải lần đầu tiên và bạn sẽ gặp lỗi trên. Chỉ khi biểu mẫu được gửi và mã này được chạy lần thứ hai thì chỉ mục mảng mới tồn tại. Bạn thường kiểm tra điều này bằng:
if ($_POST) .. // if the $_POST array is not empty
// or
if ($_SERVER['REQUEST_METHOD'] == 'POST') .. // page was requested with POST
Câu hỏi liên quan:
Cảnh báo: mysql_fetch_array () yêu cầu tham số 1 là tài nguyên, boolean đã cho
Đầu tiên và quan trọng nhất:
Vui lòng không sử dụng các
mysql_*
chức năng trong mã mới . Chúng không còn được duy trì và chính thức không được dùng nữa . Nhìn thấy ô màu đỏ ? Thay vào đó, hãytìm hiểu về các câu lệnh đã chuẩn bị và sử dụng PDO hoặc MySQLi - bài viết này sẽ giúp bạn quyết định điều đó. Nếu bạn chọn PDO, đây là một hướng dẫn tốt .
Điều này xảy ra khi bạn cố gắng tìm nạp dữ liệu từ kết quả của mysql_query
nhưng truy vấn không thành công.
Đây là một cảnh báo và sẽ không dừng tập lệnh, nhưng sẽ làm sai chương trình của bạn.
Bạn cần kiểm tra kết quả trả về mysql_query
bởi
$res = mysql_query($sql);
if (!$res) {
die(mysql_error());
}
// after checking, do the fetch
Câu hỏi liên quan:
- mysql_fetch_array () mong đợi tham số 1 là tài nguyên, boolean được cung cấp trong lựa chọn
- Tất cả "mysql_fetch_array () mong đợi tham số 1 là tài nguyên, boolean cho" Câu hỏi trên Stackoverflow
Các lỗi liên quan:
Các mysql*
hàm khác cũng mong đợi tài nguyên kết quả MySQL làm tham số sẽ tạo ra lỗi tương tự vì lý do tương tự.
Lỗi nghiêm trọng: Sử dụng $ this khi không ở trong ngữ cảnh đối tượng
$this
là một biến đặc biệt trong PHP không thể được gán. Nếu nó được truy cập trong một ngữ cảnh mà nó không tồn tại, lỗi nghiêm trọng này được đưa ra.
Lỗi này có thể xảy ra:
Nếu một phương thức không tĩnh được gọi là statically. Thí dụ:
class Foo { protected $var; public function __construct($var) { $this->var = $var; } public static function bar () { // ^^^^^^ echo $this->var; // ^^^^^ } } Foo::bar();
Cách khắc phục: xem lại mã của bạn một lần nữa,
$this
chỉ có thể được sử dụng trong ngữ cảnh đối tượng và không bao giờ được sử dụng trong phương thức tĩnh. Ngoài ra, một phương thức tĩnh không nên truy cập thuộc tính không tĩnh. Sử dụngself::$static_property
để truy cập thuộc tính tĩnh.Nếu mã từ một phương thức lớp đã được sao chép vào một hàm bình thường hoặc chỉ phạm vi toàn cục và giữ
$this
biến đặc biệt.
Cách khắc phục: Xem lại mã và thay thế$this
bằng một biến thay thế khác.
Câu hỏi liên quan:
Lỗi nghiêm trọng: Gọi đến hàm không xác định XXX
Xảy ra khi bạn cố gắng gọi một hàm chưa được xác định. Các nguyên nhân phổ biến bao gồm thiếu phần mở rộng và bao gồm, khai báo hàm có điều kiện, hàm trong khai báo hàm hoặc lỗi chính tả đơn giản.
Ví dụ 1 - Khai báo hàm có điều kiện
$someCondition = false;
if ($someCondition === true) {
function fn() {
return 1;
}
}
echo fn(); // triggers error
Trong trường hợp này, fn()
sẽ không bao giờ được khai báo vì $someCondition
không đúng.
Ví dụ 2 - Hàm trong khai báo hàm
function createFn()
{
function fn() {
return 1;
}
}
echo fn(); // triggers error
Trong trường hợp này, fn
sẽ chỉ được khai báo khi createFn()
được gọi. Lưu ý rằng các lệnh gọi tiếp theo createFn()
sẽ gây ra lỗi về Khai báo lại một chức năng Hiện có.
Bạn cũng có thể thấy điều này đối với một hàm tích hợp sẵn trong PHP. Hãy thử tìm kiếm hàm trong sách hướng dẫn chính thức và kiểm tra xem nó thuộc "phần mở rộng" (mô-đun PHP) nào và phiên bản PHP hỗ trợ nó.
Trong trường hợp thiếu tiện ích mở rộng, hãy cài đặt tiện ích mở rộng đó và kích hoạt nó trong php.ini. Tham khảo Hướng dẫn Cài đặt trong Hướng dẫn sử dụng PHP để biết tiện ích mở rộng mà chức năng của bạn xuất hiện. Bạn cũng có thể bật hoặc cài đặt tiện ích mở rộng bằng trình quản lý gói của mình (ví dụ: apt
trong Debian hoặc Ubuntu, yum
trong Red Hat hoặc CentOS) hoặc bảng điều khiển trong một môi trường lưu trữ được chia sẻ.
Nếu hàm được giới thiệu trong phiên bản PHP mới hơn từ những gì bạn đang sử dụng, bạn có thể tìm thấy các liên kết đến các triển khai thay thế trong hướng dẫn sử dụng hoặc phần nhận xét của nó. Nếu nó đã bị xóa khỏi PHP, hãy tìm thông tin về lý do, vì nó có thể không còn cần thiết nữa.
Trong trường hợp thiếu bao gồm, hãy đảm bảo bao gồm tệp khai báo hàm trước khi gọi hàm.
Trong trường hợp mắc lỗi chính tả, hãy sửa lỗi chính tả.
Câu hỏi liên quan:
Lỗi phân tích cú pháp: lỗi cú pháp, T_XXX không mong muốn
Xảy ra khi bạn có T_XXX
mã thông báo ở vị trí không mong muốn, dấu ngoặc đơn không cân bằng (không cần thiết), sử dụng thẻ ngắn mà không kích hoạt nó trong php.ini, v.v.
Câu hỏi liên quan:
- Tham khảo: Lỗi phân tích cú pháp / cú pháp PHP; và Làm thế nào để giải quyết chúng?
- Lỗi phân tích cú pháp: lỗi cú pháp: không mong muốn '{'
- Lỗi phân tích cú pháp: Lỗi cú pháp, kết thúc tệp không mong muốn trong mã PHP của tôi
- Lỗi phân tích cú pháp: lỗi cú pháp, không mong muốn '<' in - Khắc phục?
- Lỗi phân tích cú pháp: lỗi cú pháp, không mong muốn '?'
Để được trợ giúp thêm, hãy xem:
- http://phpcodechecker.com/ - Điều này cung cấp một số giải thích hữu ích hơn về những rắc rối cú pháp của bạn.
Lỗi nghiêm trọng: Không thể sử dụng giá trị trả về của hàm trong ngữ cảnh ghi
Điều này thường xảy ra khi sử dụng một hàm trực tiếp với empty
.
Thí dụ:
if (empty(is_null(null))) {
echo 'empty';
}
Điều này là do empty
là một cấu trúc ngôn ngữ chứ không phải một hàm, nó không thể được gọi với một biểu thức làm đối số của nó trong các phiên bản PHP trước 5.5. Trước PHP 5.5, đối số empty()
phải là một biến , nhưng một biểu thức tùy ý (chẳng hạn như giá trị trả về của một hàm) được cho phép trong PHP 5.5+.
empty
, mặc dù tên của nó, không thực sự kiểm tra xem một biến có "rỗng" hay không. Thay vào đó, nó sẽ kiểm tra xem một biến không tồn tại, hoặc == false
. Các biểu thức (như is_null(null)
trong ví dụ) sẽ luôn được coi là tồn tại, vì vậy ở đây empty
chỉ kiểm tra xem nó có bằng false hay không. Bạn có thể thay thế empty()
ở đây bằng !
, ví dụ if (!is_null(null))
, hoặc so sánh rõ ràng với sai, ví dụ if (is_null(null) == false)
.
Câu hỏi liên quan:
MySQL: Bạn có lỗi trong cú pháp SQL của mình; kiểm tra hướng dẫn sử dụng tương ứng với phiên bản máy chủ MySQL của bạn để biết cú pháp phù hợp để sử dụng gần ... tại dòng ...
Lỗi này thường xảy ra do bạn quên thoát đúng cách dữ liệu được chuyển đến truy vấn MySQL.
Một ví dụ về những việc không nên làm ("Ý tưởng tồi"):
$query = "UPDATE `posts` SET my_text='{$_POST['text']}' WHERE id={$_GET['id']}";
mysqli_query($db, $query);
Mã này có thể được bao gồm trong một trang có biểu mẫu để gửi, với URL chẳng hạn như http://example.com/edit.php?id=10 (để chỉnh sửa bài đăng n ° 10)
Điều gì sẽ xảy ra nếu văn bản đã gửi chứa các dấu ngoặc kép? $query
sẽ kết thúc với:
$query = "UPDATE `posts` SET my_text='I'm a PHP newbie' WHERE id=10';
Và khi truy vấn này được gửi đến MySQL, nó sẽ phàn nàn rằng cú pháp sai, vì có thêm một dấu nháy đơn ở giữa.
Để tránh những lỗi như vậy, bạn PHẢI luôn thoát khỏi dữ liệu trước khi sử dụng trong một truy vấn.
Việc thoát dữ liệu trước khi sử dụng trong một truy vấn SQL cũng rất quan trọng vì nếu bạn không làm như vậy, tập lệnh của bạn sẽ được mở để đưa vào SQL. Việc chèn SQL có thể gây ra thay đổi, mất hoặc sửa đổi bản ghi, bảng hoặc toàn bộ cơ sở dữ liệu. Đây là một vấn đề bảo mật rất nghiêm trọng!
Tài liệu:
Lỗi phân tích cú pháp: lỗi cú pháp, T_ENCAPSED_AND_WHITESPACE không mong muốn
Lỗi này thường gặp nhất khi cố gắng tham chiếu một giá trị mảng với một khóa được trích dẫn để nội suy bên trong một chuỗi được trích dẫn kép khi toàn bộ cấu trúc biến phức không được bao trong {}
.
Trường hợp lỗi:
Điều này sẽ dẫn đến Unexpected T_ENCAPSED_AND_WHITESPACE
:
echo "This is a double-quoted string with a quoted array key in $array['key']";
//---------------------------------------------------------------------^^^^^
Các bản sửa lỗi có thể có:
Trong một chuỗi được trích dẫn kép, PHP sẽ cho phép các chuỗi khóa mảng được sử dụng mà không cần trích dẫn và sẽ không cấp E_NOTICE
. Vì vậy, ở trên có thể được viết là:
echo "This is a double-quoted string with an un-quoted array key in $array[key]";
//------------------------------------------------------------------------^^^^^
Toàn bộ biến mảng phức tạp và (các) khóa có thể được đặt trong {}
, trong trường hợp đó chúng nên được trích dẫn để tránh E_NOTICE
. Tài liệu PHP đề xuất cú pháp này cho các biến phức tạp.
echo "This is a double-quoted string with a quoted array key in {$array['key']}";
//--------------------------------------------------------------^^^^^^^^^^^^^^^
// Or a complex array property of an object:
echo "This is a a double-quoted string with a complex {$object->property->array['key']}";
Tất nhiên, giải pháp thay thế cho bất kỳ điều nào ở trên là nối biến mảng vào thay vì nội suy biến mảng:
echo "This is a double-quoted string with an array variable". $array['key'] . " concatenated inside.";
//----------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^
Để tham khảo, hãy xem phần về Phân tích cú pháp biến trong trang hướng dẫn sử dụng Chuỗi PHP
Lỗi nghiêm trọng: Đã hết kích thước bộ nhớ được phép là XXX byte (đã cố gắng phân bổ XXX byte)
Không có đủ bộ nhớ để chạy tập lệnh của bạn. PHP đã đạt đến giới hạn bộ nhớ và ngừng thực thi nó. Lỗi này là nghiêm trọng, tập lệnh dừng. Giá trị của giới hạn bộ nhớ có thể được định cấu hình trong php.ini
tệp hoặc bằng cách sử dụng ini_set('memory_limit', '128 M');
trong tập lệnh (sẽ ghi đè giá trị được xác định trong php.ini
). Mục đích của giới hạn bộ nhớ là để ngăn một tập lệnh PHP chiếm hết bộ nhớ có sẵn và làm cho toàn bộ máy chủ web bị hỏng.
Điều đầu tiên cần làm là giảm thiểu dung lượng bộ nhớ mà script của bạn cần. Ví dụ: nếu bạn đang đọc một tệp lớn vào một biến hoặc đang tìm nạp nhiều bản ghi từ cơ sở dữ liệu và đang lưu trữ tất cả chúng trong một mảng, điều đó có thể sử dụng nhiều bộ nhớ. Thay đổi mã của bạn để thay vào đó đọc từng dòng tệp hoặc tìm nạp từng bản ghi cơ sở dữ liệu mà không cần lưu trữ tất cả chúng trong bộ nhớ. Điều này đòi hỏi một chút nhận thức về khái niệm về những gì đang diễn ra đằng sau hậu trường và khi dữ liệu được lưu trữ trong bộ nhớ so với những nơi khác.
Nếu lỗi này xảy ra khi tập lệnh của bạn không thực hiện công việc sử dụng nhiều bộ nhớ, bạn cần kiểm tra mã của mình để xem liệu có bị rò rỉ bộ nhớ hay không. Các memory_get_usage
chức năng là bạn của bạn.
Câu hỏi liên quan:
Cảnh báo: [function] : không mở được luồng: [lý do]
Nó xảy ra khi bạn gọi một tập tin thường là bằng include
, require
hoặc fopen
và PHP không thể tìm thấy các tập tin hoặc có không đủ quyền để tải các tập tin.
Điều này có thể xảy ra vì nhiều lý do:
- đường dẫn tập tin sai
- đường dẫn tệp là tương đối
- bao gồm đường dẫn là sai
- quyền quá hạn chế
- SELinux có hiệu lực
- và nhiều cái khác ...
Một sai lầm phổ biến là không sử dụng một đường dẫn tuyệt đối. Điều này có thể được giải quyết dễ dàng bằng cách sử dụng một đường dẫn đầy đủ hoặc các hằng số ma thuật như __DIR__
hoặc dirname(__FILE__)
:
include __DIR__ . '/inc/globals.inc.php';
hoặc là:
require dirname(__FILE__) . '/inc/globals.inc.php';
Đảm bảo đúng đường dẫn được sử dụng là một bước trong việc khắc phục sự cố này, điều này cũng có thể liên quan đến các tệp không tồn tại, quyền của hệ thống tệp ngăn truy cập hoặc mở các hạn chế dựa trên PHP của chính PHP.
Cách tốt nhất để giải quyết vấn đề này nhanh chóng là làm theo danh sách kiểm tra khắc phục sự cố bên dưới.
Câu hỏi liên quan:
Các lỗi liên quan:
Lỗi phân tích cú pháp: lỗi cú pháp, T_PAAMAYIM_NEKUDOTAYIM không mong muốn
Toán tử phân giải phạm vi còn được gọi là "Paamayim Nekudotayim" từ tiếng Do Thái פעמיים נקודתיים. có nghĩa là "dấu hai chấm".
Lỗi này thường xảy ra nếu bạn vô tình nhập ::
mã của mình.
Câu hỏi liên quan:
- Tham khảo: Lỗi phân tích cú pháp / cú pháp PHP; và Làm thế nào để giải quyết chúng?
- Hai dấu hai chấm trong PHP có nghĩa là gì?
- Sự khác biệt giữa :: (dấu hai chấm) và -> (mũi tên) trong PHP là gì?
- T_PAAMAYIM_NEKUDOTAYIM không mong đợi, chờ T_NS_Separator
Tài liệu:
Lưu ý: Sử dụng hằng số không xác định XXX - giả định là 'XXX'
hoặc, trong PHP 7.2 trở lên:
Cảnh báo: Sử dụng hằng số không xác định XXX - giả định là 'XXX' (điều này sẽ gây ra Lỗi trong phiên bản PHP trong tương lai)
Thông báo này xảy ra khi mã thông báo được sử dụng trong mã và dường như là một hằng số, nhưng một hằng số có tên đó không được xác định.
Một trong những nguyên nhân phổ biến nhất của thông báo này là không trích dẫn được một chuỗi được sử dụng làm khóa mảng kết hợp.
Ví dụ:
// Wrong
echo $array[key];
// Right
echo $array['key'];
Một nguyên nhân phổ biến khác là thiếu dấu $
(đô la) phía trước tên biến:
// Wrong
echo varName;
// Right
echo $varName;
Hoặc có lẽ bạn đã viết sai chính tả một số hằng số hoặc từ khóa khác:
// Wrong
$foo = fasle;
// Right
$foo = false;
Nó cũng có thể là một dấu hiệu cho thấy một phần mở rộng hoặc thư viện PHP cần thiết bị thiếu khi bạn cố gắng truy cập một hằng số được xác định bởi thư viện đó.
Câu hỏi liên quan:
Lỗi nghiêm trọng: Không thể khai báo lại lớp [tên lớp]
Lỗi nghiêm trọng: Không thể khai báo lại [tên hàm]
Điều này có nghĩa là bạn đang sử dụng cùng một tên hàm / lớp hai lần và cần đổi tên một trong số chúng, hoặc là do bạn đã sử dụng require
hoặc include
nơi bạn nên sử dụng require_once
hoặc include_once
.
Khi một lớp hoặc một hàm được khai báo trong PHP, nó là bất biến và sau này không thể được khai báo với giá trị mới.
Hãy xem xét đoạn mã sau:
class.php
<?php
class MyClass
{
public function doSomething()
{
// do stuff here
}
}
index.php
<?php
function do_stuff()
{
require 'class.php';
$obj = new MyClass;
$obj->doSomething();
}
do_stuff();
do_stuff();
Cuộc gọi thứ hai đến do_stuff()
sẽ tạo ra lỗi ở trên. Bằng cách thay đổi require
thành require_once
, chúng tôi có thể chắc chắn rằng tệp chứa định nghĩa của MyClass
sẽ chỉ được tải một lần và sẽ tránh được lỗi.
Chú ý: Biến không xác định
Xảy ra khi bạn cố gắng sử dụng một biến chưa được xác định trước đó.
Một ví dụ điển hình sẽ là
foreach ($items as $item) {
// do something with item
$counter++;
}
Nếu bạn không xác định $counter
trước đó, đoạn mã trên sẽ kích hoạt thông báo.
Cách đúng sẽ là đặt biến trước khi sử dụng, ngay cả khi nó chỉ là một chuỗi rỗng như
$counter = 0;
foreach ($items as $item) {
// do something with item
$counter++;
}
Tương tự, một biến không thể truy cập được bên ngoài phạm vi của nó, ví dụ khi sử dụng các hàm ẩn danh.
$prefix = "Blueberry";
$food = ["cake", "cheese", "pie"];
$prefixedFood = array_map(function ($food) {
// Prefix is undefined
return "${prefix} ${food}";
}, $food);
Thay vào đó, điều này nên được chuyển bằng cách sử dụng use
$prefix = "Blueberry";
$food = ["cake", "cheese", "pie"];
$prefixedFood = array_map(function ($food) use ($prefix) {
return "${prefix} ${food}";
}, $food);
Chú ý: Thuộc tính không xác định
Lỗi này có nghĩa tương tự, nhưng đề cập đến thuộc tính của một đối tượng. Sử dụng lại ví dụ trên, mã này sẽ gây ra lỗi vì thuộc counter
tính chưa được đặt.
$obj = new stdclass;
$obj->property = 2342;
foreach ($items as $item) {
// do something with item
$obj->counter++;
}
Câu hỏi liên quan:
- Tất cả các câu hỏi về "Thông báo: Biến không xác định" của PHP trên Stackoverflow
- "Thông báo: Biến không xác định", "Thông báo: Chỉ mục không xác định" và "Thông báo: Độ lệch không xác định" bằng PHP
- Tham khảo: Phạm vi biến là gì, những biến nào có thể truy cập từ đâu và lỗi "biến không xác định" là gì?
Lỗi phân tích cú pháp: lỗi cú pháp, T_VARIABLE không mong muốn
Kịch bản có thể xảy ra
Tôi dường như không thể tìm thấy mã của tôi đã bị sai ở đâu. Đây là lỗi đầy đủ của tôi:
Lỗi phân tích cú pháp: lỗi cú pháp, T_VARIABLE không mong muốn trên dòng x
Những gì tôi đang cố gắng
$sql = 'SELECT * FROM dealer WHERE id="'$id.'"';
Câu trả lời
Lỗi phân tích cú pháp: Một vấn đề với cú pháp của chương trình của bạn, chẳng hạn như bỏ dấu chấm phẩy ở cuối câu lệnh hoặc, giống như trường hợp trên, thiếu .
toán tử. Trình thông dịch ngừng chạy chương trình của bạn khi nó gặp lỗi phân tích cú pháp.
Nói một cách đơn giản, đây là một lỗi cú pháp, có nghĩa là có thứ gì đó trong mã của bạn ngăn nó được phân tích cú pháp chính xác và do đó chạy.
Những gì bạn nên làm là kiểm tra cẩn thận các dòng xung quanh vị trí lỗi để tìm bất kỳ lỗi đơn giản nào.
Thông báo lỗi đó có nghĩa là ở dòng x của tệp, trình thông dịch PHP đã mong đợi nhìn thấy một dấu ngoặc đơn mở nhưng thay vào đó, nó gặp phải một cái gì đó được gọi T_VARIABLE
. Thứ đó T_VARIABLE
được gọi là a token
. Đó là cách trình thông dịch PHP thể hiện các phần cơ bản khác nhau của chương trình. Khi trình thông dịch đọc trong một chương trình, nó sẽ dịch những gì bạn đã viết thành danh sách các mã thông báo. Bất cứ nơi nào bạn đặt một biến trong chương trình của mình, sẽ có một T_VARIABLE
mã thông báo trong danh sách của trình thông dịch.
Đọc hay: Danh sách mã thông báo phân tích cú pháp
Vì vậy, hãy chắc chắn rằng bạn bật ít nhất E_PARSE
trong của bạn php.ini
. Lỗi phân tích cú pháp không được tồn tại trong tập lệnh sản xuất.
Tôi luôn khuyến nghị thêm câu lệnh sau trong khi viết mã:
error_reporting(E_ALL);
Ngoài ra, một ý tưởng hay là sử dụng IDE sẽ cho bạn biết lỗi phân tích cú pháp khi nhập. Bạn có thể dùng:
- NetBeans (một phần mềm đẹp, phần mềm miễn phí) (tốt nhất theo ý kiến của tôi)
- PhpStorm (chú Gordon thích cái này: P, gói trả phí, chứa phần mềm độc quyền và miễn phí)
- Eclipse (vẻ đẹp và quái vật, phần mềm miễn phí)
Câu hỏi liên quan:
Lưu ý: Phần bù chuỗi chưa được khởi tạo: *
Như tên cho biết, loại lỗi như vậy xảy ra khi bạn rất có thể đang cố gắng lặp lại hoặc tìm một giá trị từ một mảng có khóa không tồn tại.
Hãy xem xét bạn, đang cố gắng hiển thị mọi bức thư từ $string
$string = 'ABCD';
for ($i=0, $len = strlen($string); $i <= $len; $i++){
echo "$string[$i] \n";
}
Ví dụ trên sẽ tạo ( bản trình diễn trực tuyến ):
A
B
C
D
Notice: Uninitialized string offset: 4 in XXX on line X
Và, ngay sau khi tập lệnh kết thúc lặp lại, D
bạn sẽ gặp lỗi, bởi vì bên trong for()
vòng lặp, bạn đã yêu cầu PHP hiển thị cho bạn ký tự chuỗi từ thứ nhất đến thứ năm từ chuỗi 'ABCD'
nào, tồn tại, nhưng vì vòng lặp bắt đầu đếm từ 0
và lặp lại D
vào thời điểm nó đạt đến 4
, nó sẽ tạo ra một lỗi bù đắp.
Các lỗi tương tự:
Lưu ý: Cố gắng lấy thuộc tính của lỗi không phải đối tượng
Xảy ra khi bạn cố gắng truy cập thuộc tính của một đối tượng trong khi không có đối tượng.
Một ví dụ điển hình cho một thông báo không phải đối tượng sẽ là
$users = json_decode('[{"name": "hakre"}]');
echo $users->name; # Notice: Trying to get property of non-object
Trong trường hợp này, $users
là một mảng (vì vậy không phải là một đối tượng) và nó không có bất kỳ thuộc tính nào.
Điều này tương tự như việc truy cập chỉ mục hoặc khóa không tồn tại của một mảng (xem Thông báo: Chỉ mục không xác định ).
Ví dụ này được đơn giản hóa nhiều. Thông báo như vậy thông thường nhất báo hiệu một giá trị trả về không được kiểm tra, ví dụ: khi thư viện trả về NULL
nếu một đối tượng không tồn tại hoặc chỉ là một giá trị không phải đối tượng không mong muốn (ví dụ: trong kết quả Xpath, cấu trúc JSON với định dạng không mong muốn, XML với định dạng không mong muốn, v.v.) nhưng mã không kiểm tra điều kiện như vậy.
Vì những không phải đối tượng đó thường được xử lý thêm, thường xảy ra lỗi nghiêm trọng tiếp theo khi gọi một phương thức đối tượng trên một đối tượng không phải là đối tượng (xem: Lỗi nghiêm trọng: Gọi đến một hàm thành viên ... trên một không phải đối tượng ) khiến kịch bản.
Nó có thể dễ dàng ngăn chặn bằng cách kiểm tra các điều kiện lỗi và / hoặc một biến phù hợp với một kỳ vọng. Dưới đây là một thông báo với ví dụ về DOMXPath :
$result = $xpath->query("//*[@id='detail-sections']/div[1]");
$divText = $result->item(0)->nodeValue; # Notice: Trying to get property of non-object
Vấn đề là truy cập thuộc nodeValue
tính (trường) của mục đầu tiên trong khi nó chưa được kiểm tra xem nó có tồn tại hay không trong $result
bộ sưu tập. Thay vào đó, nó trả tiền để làm cho mã rõ ràng hơn bằng cách gán các biến cho các đối tượng mà mã hoạt động:
$result = $xpath->query("//*[@id='detail-sections']/div[1]");
$div = $result->item(0);
$divText = "-/-";
if (is_object($div)) {
$divText = $div->nodeValue;
}
echo $divText;
Các lỗi liên quan:
Cảnh báo: hạn chế open_basedir có hiệu lực
Cảnh báo này có thể xuất hiện với các chức năng khác nhau liên quan đến quyền truy cập tệp và thư mục. Nó cảnh báo về sự cố cấu hình.
Khi nó xuất hiện, điều đó có nghĩa là quyền truy cập đã bị cấm đối với một số tệp.
Bản thân cảnh báo không phá vỡ bất cứ điều gì, nhưng thông thường một tập lệnh không hoạt động bình thường nếu quyền truy cập tệp bị ngăn chặn.
Cách khắc phục thông thường là thay đổi cấu hình PHP , cài đặt liên quan được gọi open_basedir
.
Đôi khi tên tệp hoặc thư mục sai được sử dụng, cách khắc phục sau đó là sử dụng đúng tên.
Câu hỏi liên quan:
Lỗi phân tích cú pháp: lỗi cú pháp, không mong muốn '['
Lỗi này có hai biến thể:
Biến thể 1
$arr = [1, 2, 3];
Cú pháp bộ khởi tạo mảng này chỉ được giới thiệu trong PHP 5.4; nó sẽ gây ra lỗi phân tích cú pháp trên các phiên bản trước đó. Nếu có thể, hãy nâng cấp cài đặt của bạn hoặc sử dụng cú pháp cũ:
$arr = array(1, 2, 3);
Xem thêm ví dụ này từ sách hướng dẫn.
Biến thể 2
$suffix = explode(',', 'foo,bar')[1];
Kết quả của hàm tham chiếu mảng cũng được giới thiệu trong PHP 5.4. Nếu không thể nâng cấp, bạn cần sử dụng một biến (tạm thời):
$parts = explode(',', 'foo,bar');
$suffix = $parts[1];
Xem thêm ví dụ này từ sách hướng dẫn.
Cảnh báo: [function] yêu cầu tham số 1 là tài nguyên, boolean đã cho
(Một biến thể chung hơn của Cảnh báo: mysql_fetch_array () mong đợi tham số 1 là tài nguyên, boolean đã cho )
Tài nguyên là một loại trong PHP (như chuỗi, số nguyên hoặc đối tượng). Tài nguyên là một đốm màu mờ đục không có giá trị vốn có ý nghĩa của riêng nó. Một tài nguyên cụ thể và được xác định bởi một tập hợp các hàm hoặc phần mở rộng PHP nhất định. Ví dụ: phần mở rộng Mysql xác định hai loại tài nguyên :
Có hai loại tài nguyên được sử dụng trong mô-đun MySQL. Cái đầu tiên là mã định danh liên kết cho một kết nối cơ sở dữ liệu, cái thứ hai là tài nguyên chứa kết quả của một truy vấn.
Phần mở rộng cURL xác định hai loại tài nguyên khác :
... một tay cầm cURL và một tay cầm nhiều cURL.
Khi chỉnh sửa var_dump
, các giá trị trông như thế này:
$resource = curl_init();
var_dump($resource);
resource(1) of type (curl)
Đó là tất cả các tài nguyên, một định danh số ( (1)
) của một loại nhất định ( (curl)
).
Bạn mang những tài nguyên này đi khắp nơi và chuyển chúng đến các chức năng khác nhau mà tài nguyên đó có ý nghĩa gì đó. Thông thường, các hàm này phân bổ dữ liệu nhất định trong nền và tài nguyên chỉ là tham chiếu mà chúng sử dụng để theo dõi dữ liệu này trong nội bộ.
Lỗi " ... mong muốn tham số 1 là tài nguyên, boolean đã cho " thường là kết quả của một hoạt động không được kiểm tra được cho là tạo ra một tài nguyên, nhưng lại được trả về false
. Ví dụ, fopen
hàm có mô tả sau:
Giá trị trả lại
Trả về tài nguyên con trỏ tệp khi thành công hoặc
FALSE
khi bị lỗi.
Vì vậy, trong mã này, $fp
sẽ là một resource(x) of type (stream)
hoặc false
:
$fp = fopen(...);
Nếu bạn không kiểm tra xem fopen
hoạt động thành công hay thất bại và do đó liệu có phải $fp
là tài nguyên hợp lệ hay không false
và chuyển $fp
sang một hàm khác mong đợi tài nguyên, bạn có thể gặp lỗi ở trên:
$fp = fopen(...);
$data = fread($fp, 1024);
Warning: fread() expects parameter 1 to be resource, boolean given
Bạn luôn cần kiểm tra lỗi giá trị trả về của các hàm đang cố gắng cấp phát tài nguyên và có thể không thành công :
$fp = fopen(...);
if (!$fp) {
trigger_error('Failed to allocate resource');
exit;
}
$data = fread($fp, 1024);
Các lỗi liên quan:
Cảnh báo: Phần bù chuỗi bất hợp pháp 'XXX'
Điều này xảy ra khi bạn cố gắng truy cập một phần tử mảng bằng cú pháp dấu ngoặc vuông, nhưng bạn đang thực hiện việc này trên một chuỗi chứ không phải trên một mảng, vì vậy thao tác rõ ràng không có ý nghĩa .
Thí dụ:
$var = "test";
echo $var["a_key"];
Nếu bạn nghĩ rằng biến phải là một mảng, hãy xem nó đến từ đâu và khắc phục sự cố ở đó.
Mã không chạy / có vẻ như các phần trong mã PHP của tôi được xuất ra
Nếu bạn không thấy kết quả nào từ mã PHP của mình và / hoặc bạn thấy các phần của đầu ra mã nguồn PHP theo nghĩa đen của mình trong trang web, bạn có thể khá chắc chắn rằng PHP của bạn không thực sự được thực thi. Nếu bạn sử dụng View Source trong trình duyệt của mình, có thể bạn đang thấy toàn bộ tệp mã nguồn PHP. Vì mã PHP được nhúng trong <?php ?>
các thẻ, trình duyệt sẽ cố gắng giải thích chúng là thẻ HTML và kết quả có thể hơi nhầm lẫn.
Để thực sự chạy các tập lệnh PHP của bạn, bạn cần:
- một máy chủ web thực thi tập lệnh của bạn
- để đặt phần mở rộng tệp thành .php, nếu không máy chủ web sẽ không hiểu nó như vậy *
- để truy cập tệp .php của bạn thông qua máy chủ web
* Trừ khi bạn cấu hình lại nó, mọi thứ đều có thể được cấu hình.
Điều cuối cùng này đặc biệt quan trọng. Chỉ cần nhấp đúp vào tệp có thể sẽ mở trong trình duyệt của bạn bằng địa chỉ như:
file://C:/path/to/my/file.php
Điều này hoàn toàn bỏ qua bất kỳ máy chủ web nào bạn có thể đang chạy và tệp không được diễn giải. Bạn cần truy cập URL của tệp trên máy chủ web của mình, có thể giống như:
http://localhost/my/file.php
Bạn cũng có thể muốn kiểm tra xem mình đang sử dụng các thẻ mở ngắn <?
thay vì <?php
và cấu hình PHP của bạn đã tắt các thẻ mở ngắn chưa.
Cũng xem mã PHP không được thực thi, thay vào đó mã hiển thị trên trang
Lưu ý: Chuyển đổi mảng thành chuỗi
Điều này chỉ xảy ra nếu bạn cố gắng coi một mảng là một chuỗi:
$arr = array('foo', 'bar');
echo $arr; // Notice: Array to string conversion
$str = 'Something, ' . $arr; // Notice: Array to string conversion
Một mảng không thể đơn giản là echo
'd hoặc được nối với một chuỗi, bởi vì kết quả không được xác định rõ. PHP sẽ sử dụng chuỗi "Array" thay cho mảng và kích hoạt thông báo để chỉ ra rằng đó có thể không phải là những gì được dự định và bạn nên kiểm tra mã của mình tại đây. Bạn có thể muốn một cái gì đó như thế này thay thế:
echo $arr[0]; // displays foo
$str = 'Something ' . join(', ', $arr); //displays Something, foo, bar
Hoặc lặp lại mảng:
foreach($arr as $key => $value) {
echo "array $key = $value";
// displays first: array 0 = foo
// displays next: array 1 = bar
}
Nếu thông báo này xuất hiện ở đâu đó mà bạn không mong đợi, nó có nghĩa là một biến mà bạn nghĩ là một chuỗi thực sự là một mảng. Điều đó có nghĩa là bạn có một lỗi trong mã của mình khiến biến này trở thành một mảng thay vì chuỗi mà bạn mong đợi.
Cảnh báo: mysql_connect (): Quyền truy cập bị từ chối đối với người dùng 'name' @ 'host'
Cảnh báo này hiển thị khi bạn kết nối với máy chủ MySQL / MariaDB với thông tin xác thực (tên người dùng / mật khẩu) không hợp lệ hoặc bị thiếu. Vì vậy, đây thường không phải là vấn đề mã, mà là vấn đề cấu hình máy chủ.
Xem trang hướng dẫn sử dụng
mysql_connect("localhost", "user", "pw")
để biết các ví dụ.Kiểm tra xem bạn có thực sự sử dụng dấu
$username
và$password
.- Việc bạn truy cập mà không cần mật khẩu là điều hiếm khi xảy ra - đó là điều đã xảy ra khi Cảnh báo: cho biết
(using password: NO)
. Chỉ máy chủ thử nghiệm cục bộ thường cho phép kết nối với tên người dùng
root
, không có mật khẩu vàtest
tên cơ sở dữ liệu.Bạn có thể kiểm tra xem chúng có thực sự chính xác hay không bằng cách sử dụng ứng dụng khách dòng lệnh:
mysql --user="username" --password="password" testdb
Tên người dùng và mật khẩu phân biệt chữ hoa chữ thường và khoảng trắng không bị bỏ qua. Nếu mật khẩu của bạn chứa các ký tự meta như
$
, hãy thoát khỏi chúng hoặc đặt mật khẩu trong dấu ngoặc kép .Hầu hết các nhà cung cấp dịch vụ lưu trữ chia sẻ đều khai báo trước tài khoản mysql liên quan đến tài khoản người dùng unix (đôi khi chỉ là tiền tố hoặc hậu tố số bổ sung). Xem tài liệu để biết mẫu hoặc tài liệu và Bảng điều khiển hoặc bất kỳ giao diện nào để đặt mật khẩu.
Xem hướng dẫn sử dụng MySQL về Thêm tài khoản người dùng bằng dòng lệnh. Khi được kết nối với tư cách là người dùng quản trị, bạn có thể đưa ra một truy vấn như:
CREATE USER 'username'@'localhost' IDENTIFIED BY 'newpassword';
Hoặc sử dụng Adminer hoặc WorkBench hoặc bất kỳ công cụ đồ họa nào khác để tạo, kiểm tra hoặc sửa chi tiết tài khoản.
Nếu bạn không thể sửa thông tin đăng nhập của mình, thì việc yêu cầu internet "vui lòng giúp đỡ" sẽ không có tác dụng. Chỉ bạn và nhà cung cấp dịch vụ lưu trữ của bạn mới có quyền và đủ quyền truy cập để chẩn đoán và sửa chữa mọi thứ.
- Việc bạn truy cập mà không cần mật khẩu là điều hiếm khi xảy ra - đó là điều đã xảy ra khi Cảnh báo: cho biết
Xác minh rằng bạn có thể truy cập máy chủ cơ sở dữ liệu bằng cách sử dụng tên máy chủ do nhà cung cấp của bạn cung cấp:
ping dbserver.hoster.example.net
Kiểm tra điều này từ bảng điều khiển SSH trực tiếp trên máy chủ web của bạn. Việc kiểm tra từ máy khách phát triển cục bộ đến máy chủ lưu trữ được chia sẻ của bạn hiếm khi có ý nghĩa.
Thường thì bạn chỉ muốn tên máy chủ
"localhost"
, thường sử dụng một ổ cắm có tên cục bộ khi có sẵn. Đôi khi bạn có thể thử"127.0.0.1"
làm dự phòng.Nếu máy chủ MySQL / MariaDB của bạn lắng nghe trên một cổng khác, sau đó sử dụng
"servername:3306"
.Nếu không thành công, thì có lẽ là do tường lửa. (Lạc đề, không phải câu hỏi lập trình. Không thể giúp đoán từ xa.)
Khi sử dụng các hằng số như vd
DB_USER
hoặcDB_PASSWORD
, hãy kiểm tra xem chúng có thực sự được xác định hay không .Nếu bạn nhận được a
"Warning: Access defined for 'DB_USER'@'host'"
và a"Notice: use of undefined constant 'DB_PASS'"
, thì đó là vấn đề của bạn.Xác minh rằng ví dụ của bạn
xy/db-config.php
đã thực sự được bao gồm hay chưa.
Kiểm tra các
GRANT
quyền được thiết lập chính xác .Không đủ để có một cặp
username
+password
.Mỗi tài khoản MySQL / MariaDB có thể có một bộ quyền đính kèm.
Những thứ đó có thể hạn chế cơ sở dữ liệu nào bạn được phép kết nối, máy khách / máy chủ mà kết nối có thể bắt nguồn từ đó và những truy vấn nào được phép.
Do đó, cảnh báo "Quyền truy cập bị từ chối" cũng có thể hiển thị cho
mysql_query
các cuộc gọi, nếu bạn không có quyền truy cậpSELECT
từ một bảng cụ thể hoặcINSERT
/UPDATE
vàDELETE
bất kỳ thứ gì phổ biến hơn .Bạn có thể điều chỉnh quyền tài khoản khi được kết nối với mỗi ứng dụng khách dòng lệnh bằng tài khoản quản trị viên với truy vấn như:
GRANT ALL ON yourdb.* TO 'username'@'localhost';
Nếu cảnh báo xuất hiện đầu tiên cùng với
Warning: mysql_query(): Access denied for user ''@'localhost'
thì bạn có thể có một cặp tài khoản / mật khẩu được định cấu hình sẵn php.ini .Kiểm tra điều đó
mysql.default_user=
vàmysql.default_password=
có các giá trị có ý nghĩa.Thông thường, đây là cấu hình của nhà cung cấp. Vì vậy, hãy liên hệ với bộ phận hỗ trợ của họ nếu không khớp.
Tìm tài liệu của nhà cung cấp dịch vụ lưu trữ được chia sẻ của bạn:
ví dụ: HostGator , GoDaddy , 1and1 , DigitalOcean , BlueHost , DreamHost , MediaTemple , ixWebhosting , Lunarhosting , hoặc chỉ google của bạn.
Nếu không, hãy tham khảo ý kiến nhà cung cấp dịch vụ lưu trữ web của bạn thông qua các kênh hỗ trợ của họ.
Lưu ý rằng bạn cũng có thể đã cạn kiệt nhóm kết nối có sẵn . Bạn sẽ nhận được cảnh báo bị từ chối truy cập cho quá nhiều kết nối đồng thời. (Bạn phải điều tra thiết lập. Đó là vấn đề cấu hình máy chủ lạc đề, không phải là câu hỏi lập trình.)
Phiên bản ứng dụng khách libmysql của bạn có thể không tương thích với máy chủ cơ sở dữ liệu. Thông thường có thể truy cập máy chủ MySQL và MariaDB bằng PHP được biên dịch trong trình điều khiển. Nếu bạn có thiết lập tùy chỉnh hoặc phiên bản PHP đã lỗi thời và máy chủ cơ sở dữ liệu mới hơn nhiều hoặc đã lỗi thời đáng kể - thì phiên bản không khớp có thể ngăn kết nối. (Không, bạn phải tự điều tra. Không ai có thể đoán được thiết lập của bạn).
Tham khảo thêm:
- Serverfault: truy cập mysql bị từ chối đối với 'root' @ 'tên của máy tính'
- Cảnh báo: mysql_connect (): Quyền truy cập bị từ chối
- Cảnh báo: mysql_select_db () Quyền truy cập bị từ chối đối với người dùng '' @ 'localhost' (sử dụng mật khẩu: NO)
- Quyền truy cập bị từ chối đối với người dùng 'root' @ 'localhost' với PHPMyAdmin
Btw, bạn có thể không muốn sử dụng các
mysql_*
chức năng nữa . Những người mới đến thường di chuyển đến mysqli , tuy nhiên, điều này cũng tẻ nhạt. Thay vào đó, hãy đọc PDO và các báo cáo đã chuẩn bị .
$db = new PDO("mysql:host=localhost;dbname=testdb", "username", "password");
Cảnh báo: Chia cho 0
Thông báo cảnh báo 'Phân chia theo số không' là một trong những câu hỏi thường gặp nhất giữa các nhà phát triển PHP mới. Lỗi này sẽ không gây ra ngoại lệ, do đó, một số nhà phát triển đôi khi sẽ ngăn chặn cảnh báo bằng cách thêm toán tử triệt tiêu lỗi @ trước biểu thức. Ví dụ:
$value = @(2 / 0);
Tuy nhiên, giống như với bất kỳ cảnh báo nào, cách tiếp cận tốt nhất sẽ là tìm ra nguyên nhân của cảnh báo và giải quyết nó. Nguyên nhân của cảnh báo sẽ đến từ bất kỳ trường hợp nào bạn cố gắng chia cho 0, một biến bằng 0 hoặc một biến chưa được gán (vì NULL == 0) vì kết quả sẽ là 'không xác định'.
Để sửa cảnh báo này, bạn nên viết lại biểu thức của mình để kiểm tra xem giá trị có phải là 0 hay không, nếu có, hãy làm việc khác. Nếu giá trị bằng 0, bạn không nên chia, hoặc bạn nên thay đổi giá trị thành 1 rồi chia để kết quả phép chia tương đương với việc chỉ chia cho biến bổ sung.
if ( $var1 == 0 ) { // check if var1 equals zero
$var1 = 1; // var1 equaled zero so change var1 to equal one instead
$var3 = ($var2 / $var1); // divide var1/var2 ie. 1/1
} else {
$var3 = ($var2 / $var1); // if var1 does not equal zero, divide
}
Câu hỏi liên quan:
Lỗi nghiêm trọng: Không thể chuyển đổi đối tượng của Class Closure thành một chuỗi
Điều đó có nghĩa là bạn không thực thi chức năng ẩn danh của mình (hoặc đóng).
Ví dụ này sẽ xảy ra lỗi khi sử dụng các hàm mũi tên:
echo $fn = fn($x = 42) => $x;
Hoặc cho bất kỳ chức năng ẩn danh nào
echo function($x = 42) { return $x; };
Để giải quyết lỗi này, bạn cần thực hiện việc đóng.
echo $fn = (fn($x = 42) => $x)(30); // take notice of the 2 sets of brackets
echo (function($x = 42) { return $x; })(30);
Loại cú pháp này được gọi là IIFE và nó đã được thêm vào trong PHP 7 .
Không được dùng nữa: Cú pháp truy cập bù đắp mảng và chuỗi có dấu ngoặc nhọn không được dùng nữa
Hiệu số chuỗi và phần tử mảng có thể được truy cập bằng dấu ngoặc nhọn {}
trước PHP 7.4.0:
$string = 'abc';
echo $string{0}; // a
$array = [1, 2, 3];
echo $array{0}; // 1
Điều này đã không được chấp nhận kể từ PHP 7.4.0 và tạo ra một cảnh báo:
Không được dùng nữa: Cú pháp truy cập bù đắp mảng và chuỗi có dấu ngoặc nhọn không được dùng nữa
Bạn phải sử dụng dấu ngoặc vuông []
để truy cập các hiệu số chuỗi và các phần tử mảng:
$string = 'abc';
echo $string[0]; // a
$array = [1, 2, 3];
echo $array[0]; // 1
Các RFC cho điều này thay đổi liên kết đến một PHP script mà cố gắng để sửa lỗi này một cách máy móc.