Да се реализира потребителски Stream Wrapper, който да позволява чрез поточния програмен интерфейс на PHP да записваме и изчитаме изображения в и от MySql база от данни.
Това е проект с няколко класа, които да ни помогнат да изследваме интерфейса на streamWrapper
класа в PHP.
Регистрира се в public/debug.php
. не прави нищо друго освен да отпечатва имената на всеки от методите на streamWrapper
интерфейса, когато биват извиквани при извикването на функциите в public/debug.php
:
fopen()
feof()
fread()
fclose()
В public/debug.php
можем да извикваме различни функции от поточния интерфейс в PHP, а \StreamWrapper\Debug
класа ще отпечати съответно извиканите методи от streamWrapper
интерфейса.
Например, с текущото съдържание на public/debug.php
:
<?php
require_once 'Bootstrap.php';
stream_wrapper_register('mydebug', '\StreamWrapper\Debug');
$fp = fopen('mydebug://notes_do.jpg', 'r');
while(!feof($fp)){
echo fread($fp, 8192) . "\n";
}
fclose($fp);
?>
... изходът на програмата ще е:
$ php -f debug.php
StreamWrapper\Debug::__construct
StreamWrapper\Debug::stream_open
StreamWrapper\Debug::stream_eof
StreamWrapper\Debug::stream_read
StreamWrapper\Debug::stream_eof
1. abc
StreamWrapper\Debug::stream_eof
StreamWrapper\Debug::stream_read
StreamWrapper\Debug::stream_eof
2. abc
StreamWrapper\Debug::stream_eof
StreamWrapper\Debug::stream_read
StreamWrapper\Debug::stream_eof
3. abc
StreamWrapper\Debug::stream_eof
StreamWrapper\Debug::stream_read
StreamWrapper\Debug::stream_eof
4. abc
StreamWrapper\Debug::stream_flush
StreamWrapper\Debug::stream_close
StreamWrapper\Debug::__destruct
$
Така вече ще се ориентираме по-лесно, кои методи от streamWrapper
интерфейса в PHP е нужно да имплементираме в нашия Custom Stream Wrapper.
Това е друг клас, който можем да регистрираме като custom stream wrapper. Той има само два магически метода:
__construct()
__call()
В конструктора конфигурира Decorator::$wrapper
променливата като инстанция на \StreamWrapper\Wrapper
класа.
Магическият метод __call()
отпечатва TRACE информация за текущо-извикания метод, след това проверява, дали в Decorator::$wrapper
инстанцията е съответният метод е имплементиран и ако е - го извиква. Ако пък не е имплементиран - програмата прекъсва изпълнението си с подходящо съобщение за грешка.
Така можем да се ориентираме, кой метод на интерфейса да имплементираме, преди да продължим с разработката на нашия custom stream wrapper.
При текущото съдържание на public/decorator.php
:
<?php
require_once 'Bootstrap.php';
stream_wrapper_register('my', '\StreamWrapper\Decorator');
$fp = fopen('my://do.jpg', 'r');
while(!feof($fp)){
echo fread($fp, 8192) . "\n";
}
fclose($fp);
?>
... изходът на програмата ще е:
$ php -f decorator.php
CREATED
# stream_open('my://notes_do.jpg', 'r', 0, NULL)
#0 [internal function]: StreamWrapper\Decorator->__call('stream_open', Array)
#1 [internal function]: StreamWrapper\Decorator->stream_open('my://notes_do.j...', 'r', 0, NULL)
#2 /stream-wrapper-debug/public/decorator.php(6): fopen('my://notes_do.j...', 'r')
#3 {main}
# stream_eof()
#0 [internal function]: StreamWrapper\Decorator->__call('stream_eof', Array)
#1 [internal function]: StreamWrapper\Decorator->stream_eof()
#2 /stream-wrapper-debug/public/decorator.php(8): feof(Resource id #11)
#3 {main}
# stream_read(8192)
#0 [internal function]: StreamWrapper\Decorator->__call('stream_read', Array)
#1 [internal function]: StreamWrapper\Decorator->stream_read(8192)
#2 /stream-wrapper-debug/public/decorator.php(9): fread(Resource id #11, 8192)
#3 {main}
# stream_eof()
#0 [internal function]: StreamWrapper\Decorator->__call('stream_eof', Array)
#1 [internal function]: StreamWrapper\Decorator->stream_eof()
#2 /stream-wrapper-debug/public/decorator.php(9): fread(Resource id #11, 8192)
#3 {main}
1. abc
# stream_eof()
#0 [internal function]: StreamWrapper\Decorator->__call('stream_eof', Array)
#1 [internal function]: StreamWrapper\Decorator->stream_eof()
#2 /stream-wrapper-debug/public/decorator.php(8): feof(Resource id #11)
#3 {main}
# stream_read(8192)
#0 [internal function]: StreamWrapper\Decorator->__call('stream_read', Array)
#1 [internal function]: StreamWrapper\Decorator->stream_read(8192)
#2 /stream-wrapper-debug/public/decorator.php(9): fread(Resource id #11, 8192)
#3 {main}
# stream_eof()
#0 [internal function]: StreamWrapper\Decorator->__call('stream_eof', Array)
#1 [internal function]: StreamWrapper\Decorator->stream_eof()
#2 /stream-wrapper-debug/public/decorator.php(9): fread(Resource id #11, 8192)
#3 {main}
2. abc
# stream_flush()
#0 [internal function]: StreamWrapper\Decorator->__call('stream_flush', Array)
#1 [internal function]: StreamWrapper\Decorator->stream_flush()
#2 /stream-wrapper-debug/public/decorator.php(12): fclose(Resource id #11)
#3 {main}
# stream_close()
#0 [internal function]: StreamWrapper\Decorator->__call('stream_close', Array)
#1 [internal function]: StreamWrapper\Decorator->stream_close()
#2 /stream-wrapper-debug/public/decorator.php(12): fclose(Resource id #11)
#3 {main}
$