PHP动态创建类的例子

1.实现一个stream_wrapper

class ClassStream {
    private $pos;
    private $stream;
    private $path;
    private static $_cache = [];
    public function stream_open($path, $mode, $options, &$opened_path) {
        $this->path = $path;
        $this->stream = self::$_cache[$path]?:'';
        $this->pos = 0;
        return true;
    }
    public function stream_read($count) {
        $ret = substr($this->stream, $this->pos, $count);
        $this->pos += strlen($ret);
        return $ret;
    }
    public function stream_write($data){
        $l=strlen($data);
        $this->stream =
            substr($this->stream, 0, $this->pos) .
            $data .
            substr($this->stream, $this->pos += $l);
        self::$_cache[$this->path] = $this->stream;
        return $l;
    }
    public function stream_eof() {
        return $this->pos >= strlen($this->stream);
    }
    public function stream_stat(){
        return true;
    }
    public function url_stat($path, $flags){
        if (!array_key_exists($path, self::$_cache)) {
            return false;
        }
        return [];
    }
}

stream_wrapper_register('class',ClassStream::class);

 

2.自动加载器

spl_autoload_register(function ($className){
    $path = 'class://' . $className;
    if(file_exists($path)) {
        require $path;
    }
});

 

3.动态创建一个类

$path = 'class://TestA';

$code = '
<?php
class TestA {
    public $b = 0;
}
';

file_put_contents($path, $code);

 

4.调用

$obj = new TestA();
var_dump($obj);

 

HTML Purifier设置允许base64图片

$config = HTMLPurifier_Config::createDefault();
$config->set('URI.AllowedSchemes', ['data'=>true,'http'=>true,'https'=>true]);
$purifier = new HTMLPurifier($config);
$clean_html = $purifier->purify($dirty_html);

不可以先get出原始数据,然后增加data=>true,再set回去。

这个地方有个奇葩的逻辑,一旦执行get就会被finalize,再set就直接抛异常,而且是fatal error。