__ngủ trong php

Trước đây chúng ta đã đề cập đến cách lưu mảng trong PHP bằng cách sử dụng serialize(), unserialize(), urlencode() và urldecode(). Lưu các đối tượng hoạt động chính xác theo cùng một cách - bạn tuần tự hóa() chúng thành một chuỗi để tạo định dạng có thể lưu được, sau đó urlencode() chúng để có được định dạng có thể truyền qua web mà không gặp vấn đề gì

Ví dụ

$poppy = new poodle('Poppy');
$safepoppy = urlencode(serialize($poppy));

Tuy nhiên, có một tính năng đặc biệt với việc lưu các đối tượng, đó là khi serialize() và unserialize() được gọi, chúng sẽ tìm kiếm một hàm __sleep() và __wakeup() trên đối tượng mà chúng đang làm việc tương ứng. Các chức năng này, mà bạn phải tự cung cấp nếu muốn chúng làm bất cứ điều gì, cho phép bạn giữ cho một đối tượng hoạt động đúng cách trong thời gian ngủ đông của nó (khi nó chỉ là một chuỗi dữ liệu)

Ví dụ: khi __sleep() được gọi, một đối tượng ghi nhật ký sẽ lưu và đóng tệp mà nó đang ghi và khi __wakeup() được gọi, đối tượng sẽ mở lại tệp và tiếp tục ghi. Mặc dù __wakeup() không cần trả về bất kỳ giá trị nào, nhưng __sleep() phải trả về một mảng các giá trị mà bạn muốn lưu. Nếu không có hàm __sleep(), PHP sẽ tự động lưu tất cả các biến, nhưng bạn có thể bắt chước hành vi này trong mã bằng cách sử dụng hàm get_object_vars() - sẽ sớm nói thêm về điều đó

Trong mã, ví dụ về trình ghi nhật ký của chúng tôi sẽ trông như thế này

class logger {
    private function __sleep() {
        $this->saveAndExit();
        // return an empty array
        return array();
    }

    private function __wakeup() {
        $this->openAndStart();
    }

    private function saveAndExit() {
        // ...[snip]...
    }

Bất kỳ đối tượng nào của lớp này được tuần tự hóa sẽ có __sleep() được gọi trên chúng, điều này sẽ lần lượt gọi saveAndExit() - một chức năng dọn dẹp thần thoại giúp lưu tệp và như vậy. Khi các đối tượng của lớp này không được đánh số thứ tự, chúng sẽ có hàm __wakeup() được gọi, hàm này sẽ gọi hàm openAndStart()

Để PHP lưu tất cả các biến bên trong hàm __sleep(), bạn cần sử dụng hàm get_object_vars(). Điều này lấy một đối tượng làm tham số duy nhất của nó và trả về một mảng gồm tất cả các biến và giá trị của chúng trong đối tượng. Bạn cần chuyển các biến để lưu lại dưới dạng các giá trị trong mảng, vì vậy bạn nên sử dụng hàm array_keys() trên giá trị trả về của get_object_vars(), như thế này

private function __sleep() {
    // do stuff here
    return array_keys(get_object_vars($this));
}

Nếu không có gì trong hàm __sleep() của bạn ngoài việc trả về mảng, bạn nên xóa hoàn toàn hàm này vì nó không khác gì những gì PHP sẽ làm theo mặc định

Nếu bạn thấy mình cần lưu các đối tượng, hãy ghi nhớ __sleep() và __wakeup() - chúng cùng nhau cho phép bạn giữ cho các đối tượng hoạt động hoàn toàn trên các trang

Bạn muốn học PHP 7?

Hacking with PHP đã được cập nhật đầy đủ cho PHP 7 và hiện có sẵn dưới dạng PDF có thể tải xuống. Nhận hơn 1200 trang học PHP thực hành ngay hôm nay

Nếu điều này hữu ích, vui lòng dành chút thời gian để nói với những người khác về Hacking với PHP bằng cách tweet về nó

Hàm này trả về một giá trị khác 0 nếu cuộc gọi bị gián đoạn bởi tín hiệu. Trên Windows, giá trị này sẽ luôn là 192, là giá trị của hằng số WAIT_IO_COMPLETION trong Windows API. Trên các nền tảng khác, giá trị trả về sẽ là số giây còn lại để ngủ

Chúng ta đã nghiên cứu trong các bài viết trước về các phương thức magiques__clone(), __set(), __get() và __call(). PHP thêm vào hai phương thức ma thuật bổ sung gần đây __sleep () và __wakeup () cho phép quá tải quy trình gốc của tuần tự hóa và hủy tuần tự hóa dữ liệu PHP. Đó là những gì chúng tôi sẽ giải thích trong phần hướng dẫn với một số ví dụ cụ thể và dễ hiểu.

Chúng tôi sẽ đề cập đến các chủ đề sau trong hướng dẫn này

Tuần tự hóa dữ liệu là gì?

Tóm lại rất đơn giản, hành động để tuần tự hóa một biến là chuyển nó thành một chuỗi chẳng hạn, lưu trữ nó trong một tệp văn bản. Ngược lại, hành động giải tuần tự hóa một chuỗi là áp dụng quy trình nghịch đảo để khôi phục biến ban đầu. Quá trình này không giới hạn ở PHP, bạn sẽ tìm thấy nó ở nhiều ngôn ngữ như Java, ActionScript, C, C # … để kể tên một số.

Các từ tuần tự hóa và khử tuần tự hóa có lẽ là những từ phổ biến nhất, nhưng bạn sẽ nghe/có thể đọc ở đâu đó các từ tuyến tính hóa / phân định tuyến tính hoặc thậm chí là sắp xếp theo thứ tự / không sắp xếp lại. Tuần tự hóa, tuyến tính hóa, sắp xếp theo thứ tự (deserialize, tương ứng và phân định không theo thứ tự) xác định các khái niệm về tuần tự hóa và giải tuần tự hóa.

Nói theo cú pháp, tuần tự hóa dữ liệu được phản ánh bằng cách sử dụng hàm serialize(), hành động ngược lại dẫn đến unserialize(). Hãy xem một số ví dụ

Tuần tự hóa/giải tuần tự hóa một biến số nguyên


   $ iVar = 1;
   $ sSerialized = serialize ($ iVar);
   $ iUnserialized = unserialize ($ sSerialized);
   echo '
';
   var_dump ($ sSerialized, $ iUnserialized);
   echo '';
?>

Đầu tiên var_dump() hiển thị chuỗi sau thành đầu ra tiêu chuẩn

chuỗi (4) “tôi. 1;”

Và thứ hai hiển thị như sau

int (1)

Bạn suy ra tất nhiên là không thú vị gì khi sắp xếp một số nguyên vì bạn có thể lưu trữ nó trực tiếp. Tuy nhiên, ví dụ này vẫn hữu ích đối với một nguyên tắc đơn giản minh họa. một tuần tự hóa biến bảo tồn loại nó. Vì vậy, chúng ta sẽ có một số nguyên trả về tốt, giống như chúng ta giữ lại một Mảng hoặc một đối tượng.

Tuần tự hóa/khử tuần tự hóa một mảng (Array)

Bây giờ hãy xem xét một bảng làm ví dụ. Tuần tự hóa và giải tuần tự hóa ở đây trở nên thú vị hơn nhiều vì chúng sẽ cho phép chúng tôi chuyển đổi (và khôi phục) toàn bộ bảng.


    $ atable = array ('Moga', 'Agra', 'Abohar', 'Punjab', 'Jaipur');
    $ sSerialized = serialize ($ atable);
    $ aUnserialized = unserialize ($ sSerialized);
    echo '
';
    var_dump ($ sSerialized, $ aUnserialized);
    echo '';
?>
The first var_dump displayed:
string (87) "a: 5: {i: 0; s: 4:" Moga"; i: 1; s: 4:"Agra"; i: 2; s: 6:"Abohar"; i: 3; s: 6: "Punjab"; i: 4; s: 6: "Jaipur";} "

Tuần tự hóa của bảng cuối cùng đã xây dựng một chuỗi ký tự có độ dài 87 ký tự. Hãy để chúng tôi nhanh chóng cấu trúc của chuỗi này

• Ký tự đầu tiên của chuỗi cho biết kiểu của biến tuần tự hóa. Ở đây, chữ cái “a” do đó chỉ ra rằng chúng ta phải tuần tự hóa một mảng (mảng)
• Sau đó ta đọc số 5 là số phần tử của mảng. Ở giữa các dấu ngoặc đơn, chúng tôi tìm thấy tất cả các phần tử của mảng
• Chữ cái đầu tiên của một nhóm phần tử cho biết loại chỉ mục trong bảng theo sau là giá trị của nó. Ở đây chúng tôi có một mảng được lập chỉ mục theo thứ tự số, vì vậy
mỗi chỉ mục là một số nguyên (“i”) có giá trị nằm trong khoảng từ 0 đến 4. Nếu chúng ta đã sử dụng một mảng kết hợp, thì các chỉ mục sẽ trở thành các chuỗi (“s”)
• Sau đó, chúng tôi đọc từng giá trị được lưu trữ, loại (“s”), độ dài của nó (4) và giá trị được lưu trữ trong bảng (“Thành phố”)

Với tất cả thông tin này, hàm unserialize() có thể xây dựng lại hoàn toàn mảng bằng cách phân tích chuỗi đã định dạng

Đây là lý do tại sao var_dump() thứ hai hiển thị kết quả mà chúng tôi tìm thấy tất cả thông tin trong chuỗi được tuần tự hóa

array(5) {
[0]=>
string(4) "Moga"
[1]=>
string(4) "Agra"
[2]=>
string(6) "Abohar"
[3]=>
string(6) "Punjab"
[4]=>
string(6) "Jaipur"
}

Bây giờ hãy thử tuần tự hóa/giải tuần tự hóa một đối tượng

Tuần tự hóa và hủy tuần tự hóa một đối tượng

Bây giờ là ví dụ thú vị nhất, tuần tự hóa một đối tượng. Hãy tham gia một lớp cơ bản với các thuộc tính khác nhau. Chúng tôi cố tình sử dụng thuộc tính công cộng, riêng tư và được bảo vệ để hình dung cách tuần tự hóa một đối tượng với các thuộc tính khác nhau.


    class Sleeper {
       protected $ _age;
       protected $ _HeadCap;
       private $ _FavoriteColor;
       public $ _tastes ;
       public function __construct () {
            $ this -> _age = 19;
            $ this -> _HeadCap = true;
            $ this -> _FavoriteColor = 'red';
            $ this -> _tastes = array ('Music', 'cinema', 'curling');
          }
   }
?>

Sau đó, chúng tôi nhận được kết quả sau đây tương ứng

string (181) "O: 7:" Sleeper ": 4: {s: 7:" * _age "; i: 19; s: 14:" * _HeadCap"; b: 1; s: 25:"FavoriteColor";s:6:"_tastes";a:3: 
{i:0;s:7:"Music";i:1;s:7:"cinema";i:2;s:7:"curling";}}
object (Sleeper) # 2 (4) {
["_age: protected"] =>
int (19)
["_HeadCap: protected"] =>
bool (true)
["_FavoriteColor: private"] =>
string (5) "Red"
["_tastes"] =>
array (3) {
[0] =>
string (7) "music"
[1] =>
string (7) "cinema"
[2] =>
string (7) "curling"
}
}

Bạn đã biết rằng biến kiểu được giữ nguyên, nó giống nhau về khả năng hiển thị (riêng tư, được bảo vệ và công khai), nó không thay đổi cấu trúc lớp theo bất kỳ cách nào. Chúng tôi đang nói về Lưu trữ sơ thẩm, chúng tôi phải cẩn thận rằng lớp của bạn được khai báo trước khi tuần tự hóa, nếu không bạn sẽ gặp lỗi

Lỗi nghiêm trọng. Không tìm thấy lớp 'Sleeper' trong /home/path/to/your/script. php trên dòng xx

Bạn sẽ nhận thấy chữ “o” là ký tự đầu tiên của chuỗi tuần tự hóa để nói rằng chúng ta có nhiều thứ để tuần tự hóa một đối tượng

Phương pháp ma thuật __sleep() và __wakeup()

Bây giờ chúng ta đã hiểu nguyên tắc tuần tự hóa, chúng ta có thể đi vào trọng tâm của vấn đề và nói về các phương thức kỳ diệu __sleep() và __wakeup()

Các phương thức này sẽ được gọi tương ứng bởi tập lệnh khi sử dụng serialize() và unserialize(). Đây là một minh họa, chúng tôi sẽ thêm __sleep() và _wakeup() vào Sleeper của chúng tôi

Tuy nhiên, phương thức __sleep() ma thuật phải thực hiện một hành động để quá trình tuần tự hóa diễn ra tốt đẹp. Ở đây người ta có thể thấy lợi ích đầu tiên của việc tuần tự hóa một thể hiện của lớp. bạn chọn thuộc tính nào của cơ thể mà bạn muốn lưu trữ. Để làm được điều này, phương thức __sleep() phải trả về một mảng chứa tên của các thuộc tính cần giữ

________số 8_______

Ở đây, một người chọn giữ tuổi đó Người ngủ, màu sắc yêu thích của cô ấy và liệu anh ấy có đội mũ trên đầu hay không

Bằng cách thực thi lại đoạn mã trên, bạn sẽ thấy cả hai tiếng vang xuất hiện sau (“Bon ben I’ll sleep. Sau đó, tốt thôi, tôi sẽ đi lấy cà phê. ”) Xác nhận rằng các phương thức __sleep() và __wakeup() đã được gọi liên tiếp

Kết quả của việc tuần tự hóa là

chuỗi (108) “O. 7. “Ký túc xá”. 3. {s. 7. “*_tuổi”; tôi. 19 ;s. 14. “* _HeadCap “;b. 1;s. 25. " Màu sắc ưa thích. 5. "mùi vị";}"

Chúng tôi thấy rằng chúng tôi không giữ những người thích Ngủ. Và đây là những gì bạn hiển thị var_dump thứ hai

object (Sleeper) # 2 (4) {
["_age: protected"] =>
int (19)
["_HeadCap: protected"] =>
bool (true)
["_FavoriteColor: private"] =>
string (5) "Red"
["_tastes"] =>
NULL
}

Lưu ý rằng chỉ các thuộc tính được chỉ định trong __sleep() đã được lưu trữ, trong khi đó thuộc tính “_tastes” bằng NULL, nội dung của nó không được lưu trữ. Tất nhiên, sự thú vị không dừng lại ở đó, bạn sẽ có thể thực hiện các hành động bạn muốn từ các phương pháp này. đồng bộ hóa với cơ sở dữ liệu, đóng kết nối với cơ sở dữ liệu khi tuần tự hóa, mở lại khi giải tuần tự hóa, v.v.

Đối với những người yêu thích DIY, cũng có thể thực hiện khái niệm “cast” đối tượng, hiện tại PHP hoàn toàn không có

__ ngủ và __ thức dậy trong PHP là gì?

Như đã mô tả, __sleep() được gọi khi bạn tuần tự hóa() một đối tượng và __wakeup() sau khi bạn hủy tuần tự hóa() nó . Tuần tự hóa được sử dụng để duy trì các đối tượng. Bạn sẽ nhận được một đại diện của một đối tượng dưới dạng một chuỗi mà sau đó có thể được lưu trữ trong $_SESSION , cơ sở dữ liệu, cookie hoặc bất kỳ nơi nào khác mà bạn muốn.

__thức dậy() trong PHP là gì?

Phương thức ma thuật __wakeup của PHP nên được dùng để khởi tạo đối tượng được tạo lại sau khi hàm unserialize được gọi . Mã khôi phục hoặc tạo lại các loại tài nguyên PHP phải ở đây, cũng như mã khôi phục bất kỳ loại thuộc tính cần thiết nào khác không được phương thức __sleep trả về.

Phương thức isset() và phương thức ma thuật __ isset() trong PHP là gì?

Hàm isset() kiểm tra xem giá trị đã được đặt hay chưa . Hàm _isset() là một phương thức kỳ diệu trong PHP. Bất kỳ chức năng nào có " _ " ở đầu đều là một phương thức kỳ diệu trong PHP.