Tham khảo - Lỗi này có ý nghĩa gì trong PHP?


1137

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 trong 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 đều được mời tham gia thêm và duy trì danh sách này.

Tại sao lại thế này?

Các câu hỏi như "Tiêu đề đã được gửi" hoặc "Gọi thành viên của một đối tượng không phải là đối tượng" xuất hiện thường xuyê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ị cho OP dòng nào sẽ thay đổi 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 vào trang web vì chúng chỉ áp dụng cho mã cụ thể của OP. Những người dùng khác có cùng lỗi không thể dễ dàng đọc giải pháp trong số đó vì họ quá cục bộ. Điều đó thật đáng buồn vì một khi bạn đã hiểu nguyên nhân gốc rễ, 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 tổng quát để áp dụng.

Tôi nên làm gì ở đây?

Nếu câu hỏi của bạn đã được đá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 cách khắc phục cho mã của bạn. Các câu trả lời thường chứa các liên kết tiếp theo để điều tra trong trường hợp không nên rõ ràng từ câu trả lời 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 lỗi "yêu thích" của bạn, mỗi câu trả lời, một mô tả ngắn nghĩa là gì (ngay cả khi nó chỉ nêu bật các thuật ngữ vào trang thủ công của họ), một giải pháp có thể hoặc cách tiếp cận gỡ lỗi và một danh sách các câu hỏi và trả lời hiện có giá trị. Ngoài ra, hãy thoải mái để cải thiện bất kỳ câu trả lời hiện có.

Danh sách

Cũng thấy:


7
Ngoài ra, để chuyển cuộc thảo luận ra khỏi các bình luận, vui lòng chuyển đến câu hỏi meta này
Earlz



Câu trả lời:


275

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ửi tiêu đề HTTP đến máy khách nhưng đã có đầu ra trước đó, dẫn đến tiêu đề đã được gửi cho máy khách.

Đây là một E_WARNINGvà nó sẽ không dừng kịch bản.

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 các tiêu đề khi nó viết <html>phần tử vào luồng đầu ra. Bạn sẽ phải di chuyển session_start()lên đầu.

Bạn có thể giải quyết điều này bằng cách đi qua các dòng trước khi mã kích hoạt Cảnh báo và kiểm tra xem nó xuất ra ở đâu. Di chuyển bất kỳ mã gửi tiêu đề trước mã đó.

Một đầu ra thường bị bỏ qua là các dòng mới sau khi đóng PHP ?>. Nó được coi là một thực hành tiêu chuẩn để bỏ qua ?>khi nó là điều cuối cùng trong tệp. Tương tự, một nguyên nhân phổ biến khác cho cảnh báo này là khi mở <?phpcó một khoảng trống, dòng hoặc ký tự vô hình trước nó, khiến máy chủ web gửi các 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ếu tệp của bạn có nhiều <?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 xây dựng 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ụ như khi mã hóa tập lệnh là UTF-8 với BOM.

Câu hỏi liên quan:


2
Nếu bạn đang sử dụng WordPress, hãy kiểm tra các tệp chủ đề. Khi tôi nâng cấp một trang web lên phiên bản mới của WordPress, tôi không thể cập nhật chủ đề vì nó đã không được cập nhật trong vài năm. Vấn đề này cắt lên. Hóa ra tệp tin.php có nhiều hơn một <? ?> khối có khoảng trắng ở giữa.
Roy Lebanon

2
@RoyLeban "Nếu tệp của bạn có nhiều hơn một khối trong đó ..." Tôi không chắc điều này có nghĩa là gì. Một "khối" là gì? Một khối sẽ bao gồm <?php ?>và vì vậy "nhiều hơn một khối" sẽ là <?php ?> <?php ?>gì?
Andrew Fox

2
Vui lòng bật tính năng 'bộ đệm đầu ra' trong tệp cấu hình PHP.ini nếu có thể. Nó được sử dụng để khắc phục sự cố này. Nó gửi tệp html được lưu trong bộ đệm đầu ra và chỉ gửi đến máy khách sau khi tập lệnh dừng, vì vậy nếu hai tiêu đề được phát hành tại vị trí khác nhau sau đó tiêu đề cũ sẽ được thay thế tiêu đề mới.
Nidhin David

191

Lỗi nghiêm trọng: Gọi đến một chức năng thành viên ... trên một đối tượng không

Xảy ra với mã tương tự như xyz->method()nơi xyzkhông phải là một đối tượng và do đó methodkhô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 tương thích về phía trước: Nó sẽ trở thành một lỗi có thể bắt đầu bắt đầu với PHP 7).

Thông thường đây là một dấu hiệu cho thấy mã bị 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, truy vấn không thể được chuẩn bị và prepare()sẽ gán falsecho $statement. Cố gắng gọi execute()phương thức sau đó sẽ dẫn đến Lỗi nghiêm trọng vì falselà "không phải đối tượng" vì giá trị là boolean.

Tìm hiểu 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 cho hàm / đối tượng / lớp cụ thể được đề cập.

Nếu thậm chí ->preparekhô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 tham số, lưu trữ dưới dạng tài sản hoặc chia sẻ thông qua phạm vi toàn cầu.

Một vấn đề khác có thể là tạo điều kiện để tạo một đối tượng 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 hiện 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:


115

Không có gì được nhìn thấy. Trang trống và trắng.

Còn được gọi là Trang trắng của cái chết hoặc Màn hình trắng của cái chết . Điều này xảy ra khi tắt báo cáo lỗi 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 sẽ nằm trong một tệp có tên "php_errors.log", ở vị trí trung tâm (ví dụ: /var/log/apache2trê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ữ được chia sẻ).

Đôi khi có thể đơn giản hơn để 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 hiển thị cho mọi người truy cập trang web.

Điều này có thể được thực hiện dễ dàng bằng cách thêm vào đầu tập lệnh mã PHP sau:

ini_set('display_errors', 1); error_reporting(~0);

Mã sẽ bật hiển thị các lỗi và đặt báo cáo lên mức cao nhất.

ini_set()được thực thi trong thời gian chạy, nó không có ảnh hưởng đến 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 cũng muốn hiển thị chúng trong đầu ra (ví dụ: trong trình duyệt), bạn phải đặt lệnh display_startup_errorsthành true. Làm điều này trong php.inihoặc trong một .htaccesshoặc bằng bất kỳ phương pháp nào khác ảnh hưởng đến cấu hình trước khi chạy .

Bạn có thể sử dụng các phương thức tương tự để đặt các lệnh log_errorserror_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:

Lỗi liên quan:


3
error_reporting(~0);tại sao không -1? Đó là những gì ~0đánh giá và ít khó hiểu hơn.
Fabrício Matté

3
Tôi nghĩ cả hai đều khó hiểu tương tự nhau. ~0IMO rõ ràng hơn: phủ định tập bit trống, tức là bật tất cả các cờ. -1 không có nghĩa là viết tắt của «không tìm thấy» như trong strpose () trong C, mà là một bitet với tất cả các cờ được đặt, bởi vì -1 là nhị phân 1111'1111'1111'1111(cho 32 bit).
kể từ

2
Rất tiếc, 1111'1111'1111'1111thực sự là 16 bit, nhưng tôi hy vọng bạn hiểu ý của tôi.
nalply

3
@IvanSolntsev, xin lỗi không, đối với các phiên bản trước 5.4, E_STRICTkhông được bao gồm trong E_ALL. php.net/manual/en/errorfunc.constants.php và cuộn xuống E_STRICT.
nalply

102

Lưu ý: Chỉ mục không xác định

Xảy ra khi bạn cố gắng truy cập một mảng bằng một khóa không tồn tại trong mảng.

Một ví dụ điển hình của Undefined Indexthông báo sẽ là ( bản demo )

$data = array('foo' => '42', 'bar');
echo $data['spinach'];
echo $data[1];

Cả hai spinach1không tồn tại trong mảng, gây ra một E_NOTICEkích hoạt.

Giải pháp là đảm bảo chỉ số hoặc phần bù tồn tại trước khi truy cập vào chỉ mục đó. Điều này có thể có nghĩa là bạn cần 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_existshoặ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 với:

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:


Tôi có xu hướng sử dụngif(!empty($_POST['message'])){ //do stuff }
Kurdtpage

85

Cảnh báo: mysql_fetch_array () dự kiến ​​tham số 1 sẽ là tài nguyên, được đưa ra boolean

Đầu tiên và quan trọng nhất:

Xin 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 bị phản đối . Thấy hộp đỏ không? Tìm hiểu về các báo cáo đã chuẩn bị thay thế và sử dụng PDO hoặc MySQLi - bài viết này sẽ giúp bạn quyết định. 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_querynhư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 cho chương trình của bạn sai.

Bạn cần kiểm tra kết quả trả về mysql_querybởi

$res = mysql_query($sql);
if (!$res) {
   die(mysql_error());
}
// after checking, do the fetch

Câu hỏi liên quan:

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à tham số sẽ tạo ra cùng một lỗi vì cùng một lý do.


5
Chỉ cần một lưu ý. Nếu mysql_querykhông đủ tệ, thêm or dievào đó là thêm sự xúc phạm đến thương tích.
Madara's Ghost

Vấn đề tôi gặp phải là $res = mysql_query($query)trả về 1 nếu truy vấn thành công nên được coi là đúng. Vì vậy khi đi qua các kết quả của mysql_query để mysql_fetch_array() các chương trình thông báo.
mboy

@mboy Đối với CHỌN, HIỂN THỊ, MÔ TẢ, GIẢI THÍCH và các câu lệnh khác trả về kết quả, mysql_query () trả về tài nguyên khi thành công hoặc SAI lỗi. Đối với các loại câu lệnh SQL khác, INSERT, UPDATE, DELETE, DROP, v.v., mysql_query () trả về TRUE khi thành công hoặc FALSE bị lỗi.
xdazz

@xdazz Đó là vấn đề tôi đang phải đối mặt, Chèn cập nhật trở về TRUE vì vậy tôi không thể thoát khỏi lỗi này mysql_fetch_array() expects parameter 1 to be resource, boolean given in select xin vui lòng xem - gist.github.com/romelemperado/93af4cdbd44ebf3a07cbfa0e3fc539d7 Bất kỳ gợi ý để Git thoát khỏi lỗi này?
mboy

2
@mboy mysql_fetch_array()là để chọn truy vấn, để chèn và cập nhật, bạn không cần tìm nạp tập kết quả (và không có tập kết quả nào cho phép bạn tìm nạp).
xdazz

79

Lỗi nghiêm trọng: Sử dụng $ this khi không ở trong bối cảnh đối tượng

$thislà một biến đặc biệt trong PHP không thể gán. Nếu nó được truy cập trong bối cảnh 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:

  1. Nếu một phương thức không tĩnh được gọi là tĩnh. 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,$thischỉ 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.

  2. 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 giữ $thisbiến đặc biệt.
    Cách khắc phục: Xem lại mã và thay thế $thisbằng một biến thay thế khác.

Câu hỏi liên quan:

  1. Gọi phương thức không tĩnh là tĩnh: PHP Lỗi nghiêm trọng: Sử dụng $ this khi không ở trong ngữ cảnh đối tượng
  2. Sao chép mã: Lỗi nghiêm trọng: Sử dụng $ this khi không ở trong bối cảnh đối tượng
  3. Tất cả các câu hỏi "Sử dụng $ this khi không có trong ngữ cảnh đối tượng" trên Stackoverflow

2
Bạn cũng có thể muốn đề cập đến cách thức hoạt động của w / đóng (ngay cả trong các phương thức không tĩnh) và cách "cố định" trong 5.4.
Kendall Hopkins

2
@hakre Tôi đang nói về một cuộc gọi tĩnh bên trong một Đóng cửa. Thích $closure = function() { self::method(); }.
Kendall Hopkins

2
@KendallHopkins: Đó là một lỗi khác: "Lỗi nghiêm trọng: Không thể tự truy cập :: khi không có phạm vi lớp nào hoạt động" Tuy nhiên, với $thisbạn có thể kích hoạt bespoken "Lỗi nghiêm trọng: Sử dụng $ this khi không ở trong ngữ cảnh đối tượng" :$closure = function() { $this->method(); };
hakre

75

Lỗi nghiêm trọng: Gọi đến chức năng không xác định XXX

Xảy ra khi bạn cố gắng gọi một chức năng chưa được xác định. Các nguyên nhân phổ biến bao gồm các phần mở rộng bị thiếu 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 tuyên bố vì $someConditionkhông đúng sự thật.

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, fnsẽ chỉ được khai báo khi createFn()được gọi. Lưu ý rằng các cuộc gọi tiếp theo createFn()sẽ gây ra lỗi về Khai báo lại chức năng Hiện có.

Bạn cũng có thể thấy điều này cho một hàm dựng sẵn PHP. Hãy thử tìm kiếm chức năng trong hướng dẫn chính thức và kiểm tra xem "phần mở rộng" (mô-đun PHP) thuộc về loại nào và phiên bản nào của 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à bậ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ụ: apttrong Debian hoặc Ubuntu, yumtrong Red Hat hoặc CentOS) hoặc bảng điều khiển trong một môi trường lưu trữ 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 hoặc phần bình luận của nó. Nếu nó đã bị xóa khỏi PHP, hãy tìm thông tin về lý do tại sao, vì nó có thể không còn cần thiết nữa.

Trong trường hợp thiếu bao gồm, đả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 lỗi chính tả, sửa lỗi chính tả.

Câu hỏi liên quan:


73

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_XXXmã thông báo ở vị trí không mong muốn, dấu ngoặc đơn (không cần thiết) không cân bằng, sử dụng thẻ ngắn mà không kích hoạt nó trong php.ini và nhiều hơn nữa.

Câu hỏi liên quan:

Để được trợ giúp thêm xem:

  • http://phpcodechecker.com/ - Điều này cung cấp một số giải thích hữu ích hơn về tai ương cú pháp của bạn.

70

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 chức năng trực tiếp với empty.

Thí dụ:

if (empty(is_null(null))) {
  echo 'empty';
}

Điều này là do emptycấu trúc ngôn ngữ và không phải là hàm, nó không thể được gọi với biểu thức là đố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 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 nếu một biến là "trống". Thay vào đó, nó kiểm tra nếu một biến không tồn tại, hoặc == false. 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 emptychỉ kiểm tra xem nó có bằng false 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 false, vdif (is_null(null) == false) .

Câu hỏi liên quan:


64

MySQL: Bạn có lỗi trong cú pháp SQL của bạn; kiểm tra hướng dẫn tương ứng với phiên bản máy chủ MySQL của bạn để biết đúng cú phá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 dữ liệu được truyền đúng vào 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 một URL như http://example.com/edit.php?id=10 (để chỉnh sửa bài đăng 10 °)

Điều gì sẽ xảy ra nếu văn bản được gửi có chứa dấu ngoặc đơn? $querysẽ 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 tới MySQL, nó sẽ phàn nàn rằng cú pháp sai, bởi vì có thêm một trích dẫn ở giữa.

Để tránh những lỗi như vậy, bạn PHẢI luôn thoát dữ liệu trước khi sử dụng trong truy vấn.

Thoát dữ liệu trước khi sử dụng trong truy vấn SQL cũng rất quan trọng vì nếu bạn không, tập lệnh của bạn sẽ được mở để tiêm SQL. Việc tiêm 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:


3
Ngoài ra, nếu bạn không, trang web của bạn sẽ bị hack bởi các bot tự động
apscience

2
@gladoscc Nhấp vào "chỉnh sửa" và sửa đổi câu trả lời. Tôi biết nó có thể được cải thiện.
Jocelyn

2
Hoặc sử dụng một truy vấn sql chuẩn bị.
Matej

53

Lỗi nghiêm trọng: Kích thước bộ nhớ cho phép của byte byte đã cạn kiệt (đã cố phân bổ byte XXX)

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à dừng thực thi nó. Lỗi này là nghiêm trọng, kịch bản dừng lại. Giá trị của giới hạn bộ nhớ có thể được cấu hình trong php.initệp hoặc bằng cách sử dụng ini_set('memory_limit', '128 M');trong tập lệnh (sẽ ghi đè lên 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 duy nhất ngấu nghiến tất cả bộ nhớ có sẵn và đưa toàn bộ máy chủ web xuống.

Điều đầu tiên cần làm là giảm thiểu dung lượng bộ nhớ mà tập lệnh của bạn cần. Chẳng hạn, nếu bạn đang đọc một tệp lớn thành 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, có thể sử dụng rất 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 các bản ghi cơ sở dữ liệu một lần mà không 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 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 hoạt động nhiều bộ nhớ, bạn cần kiểm tra mã của mình để xem có bị rò rỉ bộ nhớ hay không. Các memory_get_usagechức năng là bạn của bạn.

Câu hỏi liên quan:


53

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 giá trị mảng bằng khóa được trích dẫn để nội suy bên trong chuỗi trích dẫn kép khi toàn bộ cấu trúc biến phức không được đặt 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']";
//---------------------------------------------------------------------^^^^^

Sửa lỗi có thể:

Trong một chuỗi trích dẫn kép, PHP sẽ cho phép các chuỗi khóa mảng được sử dụng không được trích dẫn và sẽ không phát hành 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 và khóa (s) phức tạp có thể được đặt trong {}, trong trường hợp đó chúng nên được trích dẫn để tránh một E_NOTICE. Tài liệu PHP khuyến nghị 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à ghép nối biến mảng thay vì nội suy nó:

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 Chuỗi PHP


45

Cảnh báo: [chức năng] : không thể mở luồng: [lý do]

Nó xảy ra khi bạn gọi một tập tin thường là bằng include, requirehoặc fopenvà 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 đang có hiệu lực
  • và nhiều thứ khác nữa ...

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 dẫn đúng được sử dụng là một bước trong việc khắc phục cá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 chặn truy cập hoặc mở hạn chế dựa trên PHP.

Cách tốt nhất để giải quyết vấn đề này một cách nhanh chóng là làm theo danh sách kiểm tra xử lý sự cố bên dưới.

Câu hỏi liên quan:

Lỗi liên quan:


44

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ũng được gọi là "Paamayim Nekudotayim" từ tiếng Do Thái פעמפעמם có nghĩa là "đại tràng kép".

Lỗi này thường xảy ra nếu bạn vô tình nhập ::mã của bạn.

Câu hỏi liên quan:

Tài liệu:


Cách dễ nhất để kích hoạt lỗi này là chạy a()::b;hoặc $a=::;.
Ismael Miguel

43

Lưu ý: Sử dụng hằng số không xác định XXX - giả sử '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 'XXX' (điều này sẽ gây ra lỗi trong phiên bản tương lai của PHP)

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ố theo 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à do không trích dẫn 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à dấu $(đô la) bị thiếu 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ố từ khóa 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:


2
Tôi muốn nói rằng nguyên nhân phổ biến nhất là quên $ trước một biến, không phải là mảng.
Vượt qua

42

Lỗi nghiêm trọng: Không thể phân loại lại lớp [tên lớp]

Lỗi nghiêm trọng: Không thể xác định 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 requirehoặc includenơi bạn nên sử dụng require_oncehoặ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 đó không thể được khai báo với một giá trị mới.

Hãy xem xét các mã sau đây:

lớp.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 do_stuff()sẽ tạo ra lỗi ở trên. Bằng cách thay đổi requirethành require_once, chúng tôi có thể chắc chắn rằng tệp chứa định nghĩa MyClasssẽ chỉ được tải một lần và sẽ tránh được lỗi.


3
Có đáng để đề cập đến bằng cách sử dụng tự động tải và các tiêu chuẩn như PSR-4 hoặc thậm chí PSR-0 hiện đã bị loại bỏ khá nhiều bằng cách tiết kiệm cho bạn khỏi việc cần sử dụng yêu cầu / bao gồm chính bạn (loại bỏ một số trường hợp cạnh kỳ quái).
DanielM

39

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 $countertrước, mã ở trên sẽ kích hoạt thông báo.

Cách chính xác sẽ là đặt biến trước khi sử dụng, ngay cả khi đó chỉ là một chuỗi trống như

$counter = 0;
foreach ($items as $item) {
    // do something with item
    $counter++;
}

Lưu ý: Tài sản không xác định

Lỗi này có nghĩa nhiều điều tương tự, nhưng đề cập đến một 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 countertí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:


35

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 đã 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ư để lại dấu chấm phẩy ở cuối câu lệnh hoặc, như trường hợp trên, thiếu .toán tử. Trình thông dịch dừ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ó một cái gì đó trong mã của bạn ngăn không cho nó được phân tích cú pháp chính xác và do đó đang chạy.

Những gì bạn nên làm là kiểm tra cẩn thận tại các dòng xung quanh lỗi xảy ra đối với bất kỳ lỗi đơn giản nào.

Thông báo lỗi đó có nghĩa là trong dòng x của tệp, trình thông dịch PHP đã mong đợi thấy 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. Điều đó 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 các 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 một 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 bạn, có một T_VARIABLEmã thông báo trong danh sách của trình thông dịch.

Đọc tốt: Danh sách các Token Parser

Vì vậy, hãy chắc chắn rằng bạn kích hoạt ít nhất E_PARSEtrongphp.ini . Lỗi phân tích không nên tồn tại trong các kịch bản sản xuất.

Tôi luôn khuyến nghị thêm câu lệnh sau, trong khi mã hóa:

error_reporting(E_ALL);

Báo cáo lỗi PHP

Ngoài ra, một ý tưởng tốt để sử dụng IDE sẽ cho bạn biết các lỗi phân tích cú pháp trong khi gõ. Bạn có thể dùng:

  1. NetBeans (một phần đẹp, phần mềm miễn phí) (theo ý kiến ​​của tôi)
  2. PhpStorm (chú Gordon thích điều này: P, gói trả phí, chứa phần mềm độc quyền và miễn phí)
  3. Nhật thực (vẻ đẹp và quái thú, phần mềm miễn phí)

Câu hỏi liên quan:


34

Lưu ý: offset chuỗi chưa được khởi tạo: *

Như tên cho thấy, 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 với khóa không tồn tại.

Hãy xem xét bạn, đang cố gắng hiển thị mọi chữ cái từ $string

$string = 'ABCD'; 
for ($i=0, $len = strlen($string); $i <= $len; $i++){
    echo "$string[$i] \n"; 
}

Ví dụ trên sẽ tạo ra ( bản demo trực tuyến ):

A
B
C
D
Notice: Uninitialized string offset: 4 in XXX on line X

Và, ngay khi tập lệnh kết thúc lặp lại, Dbạn sẽ gặp lỗi, bởi vì bên trong for()vòng lặp, bạn đã bảo PHP chỉ cho bạn ký tự chuỗi từ thứ nhất đến thứ năm từ 'ABCD'đó, tồn tại, nhưng vì vòng lặp bắt đầu đếm 0và lặp lại Dtại thời điểm nó đạt đến 4, nó sẽ đưa ra một lỗi bù.

Lỗi tương tự:


32

Lưu ý: Đang 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 vào một tài sản của một đối tượng trong khi không có đối tượng.

Một ví dụ điển hình cho 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, $userslà 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ự với việc truy cập một 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 thường, một thông báo như vậy báo hiệu một giá trị trả về không được kiểm tra, ví dụ như 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 đối tượng không mong muốn (ví dụ: trong kết quả Xpath, cấu trúc JSON có định dạng không mong muốn, XML có định dạng không mong muốn, v.v.) nhưng mã không kiểm tra một điều kiện như vậy.

Vì các đối tượng không thường được xử lý thêm, nên thường xảy ra lỗi nghiêm trọng xảy ra khi gọi một phương thức đối tượng trên một đối tượng không (xem: 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 ) kịch bả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 kỳ vọng. Dưới đây là một thông báo với ví dụ 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 nodeValuetính (trường) của mục đầu tiên trong khi nó chưa được kiểm tra nếu nó tồn tại hay không trong $resultbộ 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 trên:

$result  = $xpath->query("//*[@id='detail-sections']/div[1]");
$div     = $result->item(0);
$divText = "-/-";
if (is_object($div)) {
    $divText = $div->nodeValue;
}
echo $divText;

Lỗi liên quan:


1
json_decodebây giờ trả về một thể hiện stdclasstheo mặc định, vì vậy mã ví dụ sẽ thực sự hoạt động.
Hugo Zink

@HugoZink: Nó thực sự (và luôn luôn làm) trả về một mảng cho ví dụ đó: 3v4l.org/SUDe0 - Bạn cũng có thể vui lòng cung cấp tài liệu tham khảo cho bài viết của mình rằng " json_decodebây giờ trả về một thể hiện stdclassmặc định" ? Tôi không thể tìm thấy điều đó trong changelog.
hakre

Theo trang hướng dẫn PHP trên json_decode , theo mặc định, assoctham số được đặt thành false. Tham số này quyết định xem hàm có trả về một stdclassthay vì mảng kết hợp hay không.
Hugo Zink

json_decode('[{"name": "hakre"}]', true)sẽ trả về một mảng, nếu không thì một stdclassđối tượng
zanderwar

29

Cảnh báo: hạn chế open_basingir 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 có liên quan đến truy cập tệp và thư mục. Nó cảnh báo về một vấn đề 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 hầu hết các tập lệnh không hoạt động đúng nếu ngăn chặn truy cập tệp.

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, sau đó sửa lỗi để sử dụng đúng tên.

Câu hỏi liên quan:


1
Điều này xảy ra thường xuyên nhất trên một máy chủ chia sẻ, người ta thường không tự khóa các thư mục :-)
uınbɐɥs

28

Lỗi phân tích cú pháp: lỗi cú pháp, không mong muốn '['

Lỗi này xuất hiện ở hai phương sai:

Biến thể 1

$arr = [1, 2, 3];

Cú pháp khởi tạo mảng này chỉ được giới thiệu trong PHP 5.4; nó sẽ đưa ra một lỗi trình 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ừ hướng dẫn.

Biến thể 2

$suffix = explode(',', 'foo,bar')[1];

Kết quả chức năng hội nghị 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 biến (tạm thời):

$parts = explode(',', 'foo,bar');
$suffix = $parts[1];

Xem thêm ví dụ này từ hướng dẫn.


23

Cảnh báo: [function] hy vọng 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 () dự kiến ​​tham số 1 sẽ là tài nguyên, được đưa ra boolean )

Tài nguyên là một loại trong PHP (như chuỗi, số nguyên hoặc đối tượng). Một tài nguyên là một đốm mờ không có giá trị có ý nghĩa vốn có của riêng nó. Một tài nguyên là 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. Chẳng hạn, phần mở rộng Mysql định nghĩa 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à định danh liên kết cho một kết nối cơ sở dữ liệu, tài nguyên thứ hai chứa kết quả của một truy vấn.

Phần mở rộng cURL định nghĩa hai loại tài nguyên khác :

... một tay cầm cURL và một tay cầm đa cURL.

Khi var_dumped, 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 nhất, 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 là 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à tài liệu tham khảo mà chúng sử dụng để theo dõi dữ liệu này trong nội bộ.


Lỗi " ... dự kiến ​​tham số 1 là tài nguyên, boolean đưa ra " thường là kết quả của một hoạt động không được kiểm soát được cho là tạo tài nguyên, nhưng falsethay vào đó được trả về . Ví dụ, fopenhàm có mô tả này:

Giá trị trả về

Trả về tài nguyên con trỏ tệp khi thành công hoặc bị FALSElỗi.

Vì vậy, trong mã này, $fpsẽ là một resource(x) of type (stream)hoặc false:

$fp = fopen(...);

Nếu bạn không kiểm tra xem fopenthao tác thành công hay thất bại và do đó $fplà tài nguyên hợp lệ hay falsevà chuyển $fpsang chức năng 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ố phân bổ 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);

Lỗi liên quan:


22

Cảnh báo: 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 điều này trên một chuỗi chứ không phải trên một mảng, vì vậy hoạt động rõ ràng không có ý nghĩa .

Thí dụ:

$var = "test";
echo $var["a_key"];

Nếu bạn nghĩ biến đó phải là một mảng, hãy xem nó đến từ đâu và khắc phục vấn đề ở đó.


20

Mã không chạy / những gì trông giống như các phần của mã PHP của tôi là đầu ra

Nếu bạn không thấy kết quả nào từ mã PHP của bạn và / hoặc bạn đang thấy các phần của đầu ra mã nguồn PHP theo nghĩa đen của bạn trong trang web, bạn có thể 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 Xem Nguồn trong trình duyệt của mình, có lẽ bạn đang xem 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 diễn giải chúng dưới dạng các thẻ HTML và kết quả có thể trông hơi khó hiểu.

Để 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 là đặc biệt quan trọng. Chỉ cần nhấp đúp vào tệp sẽ có khả năng mở tệp 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 giải thích. 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 bạn có đang sử dụng các thẻ mở ngắn <?thay vì <?phpvà cấu hình PHP của bạn đã tắt các thẻ mở ngắn.

Cũng thấy mã PHP không được thực thi, thay vào đó mã hiển thị trên trang


18

Cảnh báo: mysql_connect (): Truy cập bị từ chối đối với tên người dùng '@' máy chủ '

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 không hợp lệ hoặc thiếu (tên người dùng / mật khẩu). Vì vậy, đây thường không phải là một vấn đề mã, mà là một vấn đề cấu hình máy chủ.

  • Xem trang hướng dẫn trên mysql_connect("localhost", "user", "pw")để biết ví dụ.

  • Kiểm tra xem bạn thực sự đã sử dụng một $username$password.

    • Không có gì lạ khi bạn có quyền truy cập mà không sử dụng mật khẩu - đó 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à testtê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 máy 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ư $, thoát chúng hoặc đặt mật khẩu vào dấu ngoặc đơn .

    • Hầu hết các nhà cung cấp dịch vụ lưu trữ chia sẻ đều khai báo trước cá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ố phụ). Xem tài liệu để biết mẫu hoặc tài liệu và CPanel 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ì hãy yêu cầu internet "vui lòng giúp đỡ" sẽ không có hiệu lực. Chỉ có bạn và nhà cung cấp dịch vụ lưu trữ của bạn có quyền và đủ quyền truy cập để chẩn đoán và sửa chữa mọi thứ.

  • Xác minh rằng bạn có thể truy cập máy chủ cơ sở dữ liệu, 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. Kiểm tra từ máy khách phát triển cục bộ của bạn đế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ủ là "localhost", thông thường sử dụng một ổ cắm có tên cục bộ khi có sẵn. Những lúc khác bạn có thể thử "127.0.0.1"làm dự phòng.

    • Máy chủ MySQL / MariaDB của bạn có nên nghe trên một cổng khác không, sau đó sử dụng "servername:3306".

    • Nếu thất bại, có lẽ có vấn đề về tường lửa. (Không có chủ đề, không phải là một 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_USERhoặc DB_PASSWORD, hãy kiểm tra xem chúng có thực sự được xác định không .

    • Nếu bạn nhận được một "Warning: Access defined for 'DB_USER'@'host'"và một"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 và whatelse.

  • Kiểm tra GRANTquyền đặt chính xác .

    • Nó không đủ để có dấu username+password cặp .

    • Mỗi tài khoản MySQL / MariaDB có thể có một bộ quyền được đính kèm.

    • Những người này có thể hạn chế cơ sở dữ liệu nào bạn được phép kết nối, từ đó máy khách / máy chủ mà kết nối có thể bắt nguồn từ đó và truy vấn nào được phép.

    • Do đó, cảnh báo "Truy cập bị từ chối" cũng có thể hiển thị cho mysql_querycác cuộc gọi, nếu bạn không có quyền SELECTtừ một bảng cụ thể hoặc INSERT/ UPDATE, và phổ biến hơn DELETEbất cứ điều gì.

    • Bạn có thể điều chỉnh quyền tài khoản khi được kết nối trên mỗi máy 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 trước tiên Warning: mysql_query(): Access denied for user ''@'localhost'thì bạn có thể có cặp tài khoản / mật khẩu được cấu hình sẵn php.ini .

    • Kiểm tra điều đó mysql.default_user=mysql.default_password=có giá trị có ý nghĩa.

    • Thông thường, đây là một cấu hình nhà cung cấp. Vì vậy, liên hệ với hỗ trợ của họ cho không phù hợp.

  • Tìm tài liệu của nhà cung cấp dịch vụ lưu trữ chia sẻ của bạn:

  • Lưu ý rằng bạn cũng có thể đã cạn kiệt nhóm kết nối khả dụng . Bạn sẽ nhận được quyền truy cập từ chối cảnh báo 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ủ ngoài chủ đề, không phải câu hỏi lập trình.)

  • Phiên bản máy 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ác máy chủ MySQL và MariaDB có thể được tiếp cận với các PHP được biên dịch trong trình điều khiển. Nếu bạn có một thiết lập tùy chỉnh, hoặc một phiên bản PHP lỗi thời và một 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 thiết lập của bạn).

Tham khảo thêm:

Btw, có lẽ bạn 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 lên PDO và chuẩn bị các tuyên bố .
$db = new PDO("mysql:host=localhost;dbname=testdb", "username", "password");


2
mysql cho phép tự động kết nối thông qua cài đặt php-ini, sau đó thông báo lỗi tương tự được đưa ra với các lệnh khác nhau có tiền tố, ví dụ: "Cảnh báo: mysql_query (): Truy cập bị từ chối cho người dùng '' @ 'localhost' (sử dụng mật khẩu: NO). .. " - chỉ cần lưu ý.
hakre

Ha, hoàn toàn quên mất điều đó! (Có lẽ là lần cuối sử dụng với PHP3 hoặc hơn ..)
mario

18

Lưu ý: Chuyển đổi mảng thành chuỗi

Điều này chỉ đơn giản 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ể chỉ đơn giản là echo'd hoặc nối với một chuỗi, vì kết quả không được xác định rõ. PHP sẽ sử dụng chuỗi "Mảng" thay cho mảng và kích hoạt thông báo để chỉ ra rằng đó có thể không phải là mục đích 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 vào đó:

echo $arr[0];  // displays foo
$str = 'Something ' . join(', ', $arr); //displays Something, foo, bar

Hoặc lặp 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, điều đó 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 bạn, điều này làm cho biến này trở thành một mảng thay vì chuỗi bạn mong đợi.


12

Cảnh báo: Chia cho số không

Thông báo cảnh báo 'Chia cho số 0' là một trong những câu hỏi thường gặp nhất trong số 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ẽ 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);

Nhưng, 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à theo dõi 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ố chia cho 0, một biến bằng 0 hoặc một biến chưa được chỉ định (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ị không phải là 0, nếu có, hãy làm một cái gì đó 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 và sau đó chia để kết quả 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:


Đặt thành 1 nếu là 0 sẽ dừng lỗi nhưng điều này có thực sự tốt hơn sự triệt tiêu mà bạn nói không nên sử dụng (mà tôi đồng ý)? Tôi đề nghị nhiều lần có thể một số tin nhắn hoặc giá trị khác sẽ được trả lại.
James

Trong ví dụ này, nếu $var1does == 0 thì bạn có thể đặt $var3thành $var2. Ngay cả khi không làm điều đó, thì điều đó hoàn toàn không cần thiết vì sự phân công là giống nhau trong cả hai trường hợp nên không có gì khác và chỉ định bên ngoàiif
James

8

Tiêu chuẩn nghiêm ngặt: Không nên gọi phương thức tĩnh [<class> :: <phương thức>]

Xảy ra khi bạn cố gắng gọi một phương thức không tĩnh trên một lớp vì nó là tĩnh và bạn cũng có E_STRICTcờ trong error_reporting()cài đặt của mình .

Thí dụ :

class HTML {
   public function br() {
      echo '<br>';
   }
}

HTML::br() hoặc là $html::br()

Bạn thực sự có thể tránh lỗi này bằng cách không thêm E_STRICTvào error_reporting(), vd

error_reporting(E_ALL & ~E_STRICT);

vì đối với PHP 5.4.0 trở lên, E_STRICTđược bao gồm trong E_ALL[ ref ]. Nhưng điều đó không được khuyến khích. Giải pháp là xác định hàm tĩnh dự định của bạn là thực tế static:

public static function br() {
  echo '<br>';
}

hoặc gọi hàm thông thường:

$html = new HTML();
$html->br();

Câu hỏi liên quan :


7

Không dùng nữa: Cú pháp truy cập bù mảng và chuỗi với dấu ngoặc nhọn không được dùng nữa

Chuỗi bù và các 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 cảnh báo:

Không dùng nữa: Cú pháp truy cập bù mảng và chuỗi với 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 offset chuỗi và thành phần 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.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.