Luồng tệp trong PHP

Ghi chú. Bài đăng này đã hơn hai năm tuổi và vì vậy thông tin ở đây có thể đã lỗi thời. Nếu bạn phát hiện ra điều gì đó, vui lòng để lại nhận xét và chúng tôi sẽ cố gắng khắc phục

Ngày 13 tháng 12 năm 2019 - Thời gian đọc 14 phút

Luồng là một cách khái quát hóa tệp, mạng, tài nguyên nén và một vài thứ khác theo cách cho phép chúng chia sẻ một bộ tính năng chung. Tôi phát trực tuyến là một đối tượng tài nguyên có hành vi có thể phát trực tuyến. Nó có thể được đọc hoặc ghi theo kiểu tuyến tính, nhưng không nhất thiết là từ đầu luồng

Luồng đã có sẵn trong PHP từ khá lâu (ít nhất là từ phiên bản 4. 3. 0) và được sử dụng khá rõ ràng bởi hầu hết các lập trình viên PHP. Chúng có thể được sử dụng để truy cập các tệp, tài nguyên mạng, đối số dòng lệnh, hầu hết mọi thứ đi qua luồng đầu vào/đầu ra trong PHP

Gần đây tôi đã xem xét ReactPHP và nhận thấy rằng việc sử dụng các luồng là một yêu cầu để tránh chặn luồng đầu vào/đầu ra. Mặc dù, tôi đã thấy các luồng được sử dụng trong các ứng dụng PHP, nhưng bản thân tôi không hoàn toàn chắc chắn về cách sử dụng chúng. Kết quả là tôi nghĩ mình nên viết một bài về họ

Các luồng đặc biệt hữu ích khi truy cập các tệp lớn. Giả sử chúng ta cần truy cập tệp nhật ký có kích thước vài trăm MB. Chúng tôi chỉ có thể đọc tệp vào bộ nhớ với file_get_contents() và sau đó chạy qua nội dung cho đến khi chúng tôi tìm thấy thứ mình cần. Vấn đề với cách tiếp cận này là chúng tôi sẽ nhanh chóng hết tài nguyên hệ thống và chương trình sẽ bị lỗi trước khi chúng tôi có cơ hội truy cập dữ liệu

Một giải pháp tốt hơn nhiều cho vấn đề này là sử dụng các luồng PHP. Chúng ta có thể sử dụng hàm fopen() để xử lý tệp và sau đó truyền tệp mỗi lần một chút, do đó giảm dung lượng bộ nhớ cần thiết để đọc tệp

$handle = fopen('logfile.log', 'r');
while (false !== ($line = fgets($handle))) {
  // Do something.
}

Đây là cách sử dụng luồng minh bạch mà tôi đã đề cập ở trên. Mặc dù chúng tôi chưa sử dụng rõ ràng bất kỳ chức năng hoặc cú pháp luồng nào nhưng chúng tôi vẫn đang sử dụng các luồng PHP để đọc các đoạn của tệp

Cú pháp luồng

Bạn có thể truy cập các luồng trực tiếp bằng cú pháp [scheme]. //[Mục tiêu]. Lược đồ là tên của trình bao bọc và mục tiêu là những gì đang được đọc hoặc viết, điều này phần lớn phụ thuộc vào thứ đang được đọc. PHP có một số trình bao bọc, vận chuyển và bộ lọc luồng được tích hợp sẵn khác nhau. Bạn có thể tìm hiểu những gì họ đang sử dụng ba chức năng sau

Trên hệ thống hiện tại của tôi, kết quả này xuất ra

Array
(
    [0] => tcp
    [1] => udp
    [2] => unix
    [3] => udg
    [4] => ssl
    [5] => tls
    [6] => tlsv1.0
    [7] => tlsv1.1
    [8] => tlsv1.2
)
Array
(
    [0] => https
    [1] => ftps
    [2] => compress.zlib
    [3] => compress.bzip2
    [4] => php
    [5] => file
    [6] => glob
    [7] => data
    [8] => http
    [9] => ftp
    [10] => phar
    [11] => zip
)
Array
(
    [0] => zlib.*
    [1] => bzip2.*
    [2] => convert.iconv.*
    [3] => string.rot13
    [4] => string.toupper
    [5] => string.tolower
    [6] => string.strip_tags
    [7] => convert.*
    [8] => consumed
    [9] => dechunk
)

Điều này cung cấp nhiều tùy chọn để kết nối với tất cả các loại luồng

php. // Suối

Được xây dựng trong php. // stream có lẽ là trình bao bọc stream linh hoạt nhất và là điểm khởi đầu tốt để xem cách sử dụng stream. Một ví dụ về php. // trình bao bọc đang được sử dụng với mục tiêu stdin. Đây là luồng chỉ đọc sẽ đọc đầu vào từ đầu vào tiêu chuẩn và tạo luồng đó dưới dạng luồng trong PHP. Sau đó chúng ta có thể đọc nội dung của luồng thông qua hàm fgets(). Điều này đọc một dòng tại một thời điểm, nhưng tốt cho những gì chúng tôi đang làm. Chúng ta cũng có thể sử dụng fread() để làm điều này

$stdin = fopen('php://stdin', 'r');
while (false !== ($line = fgets($stdin))) {
    echo $line;
}

Tập lệnh này có thể được sử dụng bằng cách đưa đầu ra của tệp vào tập lệnh trên dòng lệnh

cat somelog.log | php stream.php

Đầu ra của tập lệnh là nội dung của tệp được in trên dòng lệnh, nhưng ý tưởng cốt lõi của việc chuyển thành tập lệnh PHP được nêu ở đây

Một ví dụ khác là sử dụng php. //đầu vào để đọc đầu vào cho tập lệnh. Đây là một luồng chỉ đọc khác có thể được sử dụng để đọc nội dung thô của các yêu cầu POST đối với tập lệnh. Giả sử chúng tôi đã gọi một tập lệnh với yêu cầu cuộn tròn sau

curl -X POST -d "data1=thing" -d "data2=anotherthing" "http://localhost:8000/stream.php"

Chúng ta có thể truy cập dữ liệu POST bằng cách sử dụng biến siêu toàn cục $_POST

print_r($_POST);

Điều này sẽ in ra như sau

Array
(
    [data1] => thing
    [data2] => anotherthing
)

Bằng cách sử dụng php. // đầu vào, chúng ta có thể đọc trực tiếp nội dung của dữ liệu POST dưới dạng luồng đầu vào

________số 8

Điều này xuất ra như sau

data1=thing&data2=anotherthing

php. // bộ nhớ và php. //nhiệt độ

PHP5. 1 php giới thiệu. // bộ nhớ và php. // temp cho phép đọc và ghi vào bộ nhớ hoặc tệp tạm thời

php. // bộ nhớ có thể được sử dụng theo cách tương tự như php. //luồng đầu vào, nhưng trong trường hợp này chúng ta có thể đọc và ghi vào nó. Đây là một ví dụ về việc mở một luồng bộ nhớ và sau đó ghi một số dữ liệu vào đó

0

Không có tệp nào được tạo trong mã này, chúng tôi chỉ ghi vào bộ nhớ. Chúng tôi cũng có thể đọc từ luồng bộ nhớ như bình thường với các tệp và luồng. Lưu ý rằng bạn không thể thực hiện việc này ngay lập tức, trước tiên chúng ta phải tua lại con trỏ về đầu luồng trước khi có thể đọc nội dung của luồng. Điều này có thể được thực hiện bằng cách sử dụng hàm rewind()

1

php. // luồng tạm thời hoạt động như php. // bộ nhớ, nhưng điểm khác biệt quan trọng là nếu bạn ghi nhiều hơn một lượng dữ liệu nhất định (theo mặc định là 2 MB) thì một tệp sẽ được tạo để lưu trữ thông tin này. Vị trí của tệp này tùy thuộc vào hệ thống của bạn, nhưng bạn có thể tìm thấy thông tin này bằng cách sử dụng hàm sys_get_temp_dir(). Tệp này sẽ tự động bị xóa khi tập lệnh PHP kết thúc

Cũng có thể kiểm soát lượng dữ liệu bạn có thể thêm vào php. // luồng tạm thời trước khi tệp được tạo. Điều này được thực hiện bằng cách nối thêm "/maxmemory. n", trong đó 'n' là lượng dữ liệu tối đa cần lưu trong bộ nhớ trước khi sử dụng tệp tạm thời, tính bằng byte

2

Với điều đó, nếu dữ liệu chúng ta ghi vượt quá 1028 byte thì một tệp sẽ được tạo trong thư mục tạm thời

Truyền phát một trang web

Bạn có thể đã thấy rằng http và https có sẵn dưới dạng trình bao bọc luồng. Điều này có nghĩa là chúng ta có thể mở một trang web dưới dạng tài nguyên luồng và truyền nó dưới dạng dữ liệu. Đây là một ví dụ về điều này trong hành động

3

Điều này trả về đầu ra sau

4

Lưu ý rằng chúng tôi đang cắt bỏ phần cuối của thẻ html, nhưng điều này là do chúng tôi chỉ đọc 50 byte dữ liệu đầu tiên, đây là nơi dừng dữ liệu

bộ lọc

Bộ lọc là một dạng siêu luồng cho phép bạn thao tác dữ liệu khi dữ liệu đi qua luồng. Điều này có nghĩa là bạn có thể thêm bộ lọc vào lệnh gọi hàm như readfile() hoặc fopen() mà không phải thay đổi dữ liệu trước (hoặc sau) dữ liệu đi qua luồng. Cú pháp của bộ lọc là php. //filter/read=[filter]/resource=[stream] với bộ lọc từ stream_get_filters() ở trên và luồng là bất kỳ luồng nào có thể sử dụng được

Ví dụ: chúng ta có thể mở rộng trên php. // ví dụ stdin ở trên bằng cách chuyển đầu vào qua bộ lọc. Trong trường hợp này, chúng tôi đang thay đổi tất cả văn bản thành chữ hoa

5

Một ví dụ khác là trao đổi phần tài nguyên với một địa chỉ web. Thao tác này sẽ mở địa chỉ web dưới dạng luồng

6

Khi chúng tôi đọc nội dung của luồng được lọc, nó sẽ ở dạng chữ hoa

Chúng ta có thể làm ngược lại điều này bằng cách sử dụng file_put_contents() với thiết lập bộ lọc tương tự. Đoạn mã bên dưới sẽ viết văn bản 'hashbangcode', bằng chữ in hoa, vào một tệp có tên là văn bản trên. txt. Lưu ý việc sử dụng bộ lọc ghi thay vì bộ lọc đọc

7

Bối cảnh truyền phát

Một phần mạnh mẽ khác của luồng là tạo ngữ cảnh. Điều này cho phép chúng tôi thay đổi cách sử dụng các luồng. Ví dụ: khi chúng tôi sử dụng hàm file_get_contents() để truy cập một URL, nó sẽ luôn thực hiện việc này bằng cách sử dụng yêu cầu GET

8

Để thay đổi loại yêu cầu đang được thực hiện, chúng tôi tạo ngữ cảnh luồng và chuyển yêu cầu này cho hàm. Ngữ cảnh luồng được tạo bằng hàm stream_context_create(), hàm này lấy một mảng mô tả chi tiết ngữ cảnh cần tạo

Sau đây là ví dụ về cách tạo bối cảnh cần thiết để tạo yêu cầu POST (bao gồm nội dung của yêu cầu) bằng cách sử dụng stream_context_create() và sau đó sử dụng file_get_contents(). Tôi đang sử dụng https. // người đưa thư-echo. com/post/ để kiểm tra yêu cầu bài đăng này vì nó sẽ trả lại bất kỳ thứ gì bạn đã gửi và đó là một cách tốt để kiểm tra xem mọi thứ có hoạt động không

9

Chạy cái này trả về như sau

Array
(
    [0] => tcp
    [1] => udp
    [2] => unix
    [3] => udg
    [4] => ssl
    [5] => tls
    [6] => tlsv1.0
    [7] => tlsv1.1
    [8] => tlsv1.2
)
Array
(
    [0] => https
    [1] => ftps
    [2] => compress.zlib
    [3] => compress.bzip2
    [4] => php
    [5] => file
    [6] => glob
    [7] => data
    [8] => http
    [9] => ftp
    [10] => phar
    [11] => zip
)
Array
(
    [0] => zlib.*
    [1] => bzip2.*
    [2] => convert.iconv.*
    [3] => string.rot13
    [4] => string.toupper
    [5] => string.tolower
    [6] => string.strip_tags
    [7] => convert.*
    [8] => consumed
    [9] => dechunk
)
0

Một ví dụ điển hình khác về việc sử dụng ngữ cảnh luồng là khi bỏ qua các quy tắc SSL nghiêm ngặt mà PHP có. Giả sử chúng tôi đang cố kết nối với máy chủ cục bộ không có chứng chỉ SSL được ký đầy đủ. Chúng tôi có thể tạo ngữ cảnh luồng cho phép bỏ qua bước xác minh SSL

Array
(
    [0] => tcp
    [1] => udp
    [2] => unix
    [3] => udg
    [4] => ssl
    [5] => tls
    [6] => tlsv1.0
    [7] => tlsv1.1
    [8] => tlsv1.2
)
Array
(
    [0] => https
    [1] => ftps
    [2] => compress.zlib
    [3] => compress.bzip2
    [4] => php
    [5] => file
    [6] => glob
    [7] => data
    [8] => http
    [9] => ftp
    [10] => phar
    [11] => zip
)
Array
(
    [0] => zlib.*
    [1] => bzip2.*
    [2] => convert.iconv.*
    [3] => string.rot13
    [4] => string.toupper
    [5] => string.tolower
    [6] => string.strip_tags
    [7] => convert.*
    [8] => consumed
    [9] => dechunk
)
1

Phần kết luận

Có rất nhiều luồng trong PHP hơn những gì tôi đã trình bày chi tiết ở đây. PHP bao gồm một loạt các chức năng cho phép bạn tương tác với các luồng theo nhiều cách khác nhau. Cũng có thể tạo các trình bao bọc và bộ lọc luồng tùy chỉnh mà tôi có thể trình bày chi tiết trong các bài đăng sau

PHP

suối

stream_context_create

phản ứng PHP

Xoăn

Luồng tệp trong PHP

Được viết bởi. Philip Norton

Phil là người sáng lập và quản trị viên của #. viết mã và là một chuyên gia CNTT làm việc ở Tây Bắc Vương quốc Anh. Tốt nghiệp năm 2003 tại Đại học Aberystwyth với bằng Thạc sĩ Khoa học Máy tính Phil trước đây đã từng làm quản trị viên cơ sở dữ liệu, trên bàn trợ giúp CNTT, huấn luyện viên hệ thống, kiến ​​trúc web, tư vấn khả năng sử dụng, blogger và chuyên gia SEO. Phil có nhiều kinh nghiệm xây dựng và duy trì các trang web PHP cũng như làm việc với các công nghệ liên quan như JavaScript, HTML, CSS, XML, Flex, Apache, MySQL và Linux

Mục đích của tệp () trong PHP là gì?

Tệp() đọc tệp thành một mảng . Mỗi phần tử mảng chứa một dòng từ tệp, với ký tự xuống dòng vẫn được đính kèm.

Làm cách nào để đọc từ tệp bằng PHP?

Tệp đọc PHP - fread() . Tham số đầu tiên của fread() chứa tên của tệp để đọc và tham số thứ hai chỉ định số byte tối đa để đọc.

Làm cách nào để lưu dữ liệu trong tệp trong PHP?

PHP Ghi vào Tệp - fwrite() . Tham số đầu tiên của fwrite() chứa tên của tệp cần ghi và tham số thứ hai là chuỗi được ghi.

Làm cách nào để tạo một tệp có thể tải xuống bằng PHP?

PHP cho phép bạn tải xuống tệp dễ dàng bằng hàm readfile() tích hợp. Hàm readfile() đọc một tệp và ghi nó vào bộ đệm đầu ra. .
tiêu đề ('Loại nội dung. ứng dụng/octet-stream');
tiêu đề ("Mã hóa chuyển nội dung. utf-8");