以下部分内容来自手册,比如这个列表:
- Filesystem
- HTTP and HTTPS
- FTP and FTPS
- PHP input/output streams
- Compression Streams
- Data (RFC 2397)
- Glob
- Phar
- Secure Shell 2
- Audio Streams
- Process Interaction Streams
对于这个列表,熟悉的人可能很熟悉,不熟悉的人,应该不太会关注,以前我也一样。
直到,我看到zend framework,发现在zend_view里,他就模拟了一个协议:zend.view://,为的就是将那些模版中采用短标签(<? =$a ?>)的代码改为长标签(<?php echo $a ; ?>)。
其实我再次看它,也只是一个顺便。yhustc想尝试把以下内容输出:
- <?php
- $str = '今天是:<?php echo date("Y-m-d"); ?>';
- file_put_contents('test.php', $str );
- include( 'test.php' );
输出结果是类似:今天是2009-01-01这样的结果,但事实上的输出却还是
- 今天是:<?php echo date("Y-m-d"); ?>
yhustc进行了尝试,如果这个内容写入文件,然后通过include,就可以显示正确的结果:
- <?php
- $str = '今天是:<?php echo date("Y-m-d"); ?>';
- file_put_contents('test.php', $str );
- include( 'test.php' );
但是yhustc不想要这个多出来的IO,因为写入文件后,你总还得删除吧?如果类似的东西太多,IO就太恐怖了。
于是我根据zend.view://这个协议,想起了PHP自带的。并使用Data的协议或者称Wrappers来解决了这个问题:
- $str = "函数使用 今天的日期: <?php echo date('Y-m-d');?>";
- $strBase64 = base64_encode( $str );
- include("data://text/plain;base64,{$strBase64}") ;
关于这个data的wrappers请查看上面的列表,我也就不详细说了,它是符合RRC2397的标准的。
事实上这个Data也是从5.2.0才开始支持的,而且更重要的是上面的第三行代码:
- include("data://text/plain;base64,{$strBase64}") ;
这句话还需要另外一样东西支持:allow_url_include,而这个又需要allow_url_open的支持。(需要改php.ini)
有了这个支持,你以后看到这样的代码:
- <?php
- include("http://localhost/needrequire.php");
- echo 'test';
就不需要更感到惊讶和愤怒了。毕竟,它事实上是支持的,只要这个needrequire.php是返回正确的PHP代码,比如test.php的内容为:
- <?php
- echo( '<?php class a{ function a(){echo "test";}}?>' );
- ?>
然后:
- <?php
- include( 'http://localhost/test_echo.php' );
- $a = new a();
还是会正常的输出test的。