2013-07-19 81 views
0

這樣做的最佳方式是什麼? 我給了一個模板,裏面有一些東西,比如{:HELLO-WORLD:}標籤。評估插件系統

我也給喜歡的數組:

Array 
(
[0] => Array 
    (
     [Name] => {:HELLO-WORLD:} 
     [Plugin] => "<?php return 'Hello World'; ?>" 
     [Settings] => 
    ) 

) 

我能做些什麼,以確保{:HELLO-WORLD:}得到與Hello World輸出更換?

我目前正在嘗試:

private function PluginReplacer($arr, $str){ 
     $gsCt = count($arr); 
     $kv = array(); 
     for ($i=0;$i<$gsCt;++$i){ 
      $kv[$arr[$i]['Name']] = $arr[$i]['Plugin']; 
     } 
     return str_replace(array_keys($kv), $this->EvalCode(array_values($kv)), $str); 
    } 

    // Eval Some Code 
    private function EvalCode($var){ 
     require_once('plugins.php'); 
     $pr = new CloudCMSPluginRunner(); 
     $pr->Code = $var; 
     $pr->SitePath = GetSiteAssetsPath($this->SiteID); 
     $pr->RunIt(); 
     echo $pr->Error; 
    } 

<?php 

class CloudCMSPluginRunner { 

public $Code = ''; 
public $Error = ''; 
public $SitePath = ''; 
private $DoNotAllow = array('echo', 'eval', 'phpinfo', '/`/', 'chmod', 'chown', 'umask', 'shell_exec', 
          'exec', 'escapeshellcmd', 'proc_open', 'proc_terminate', 'proc_get_status', 
          'passthru', 'proc_nice', 'system', 'escapeshellarg', 'ob_start', 'ob_end_clean', 
          'ob_get_clean', 'session_start', 'putenv', 'header', 'sleep', 'uwait', 'ini_set', 
          'error_reporting', 'chgrp', 'basename', 'clearstatcache', 'copy', 'delete', 
          'dirname', 'disk_free_space', 'disk_total_space', 'diskfreespace', 'fclose', 
          'feof', 'fflush', 'fgetc', 'fgetcsv', 'fgets', 'fgetss', 'file_exists', 'file_get_contents', 
          'file_put_contents', 'file', 'fileatime', 'filectime', 'filegroup', 'fileinode', 'filemtime', 
          'fileowner', 'fileperms', 'filesize', 'filetype', 'flock', 'fnmatch', 'fopen', 'fpassthru', 
          'fputcsv', 'fputs', 'fread', 'fscanf', 'fseek', 'fstat', 'ftell', 'ftruncate', 'fwrite', 'glob', 
          'is_dir', 'is_executable', 'is_file', 'is_link', 'is_readable', 'is_uploaded_file', 'is_writeable', 
          'is_writable', 'lchgrp', 'lchown', 'link', 'linkinfo', 'lstat', 'mkdir', 'move_uploaded_file', 
          'parse_ini_file', 'parse_ini_string', 'pathinfo', 'pclose', 'popen', 'readfile', 'readlink', 
          'realpath_cache_get', 'realpath_cache_size', 'realpath', 'rename', 'rewind', 'rmdir', 'set_file_buffer', 
          'stat', 'symlink', 'tempnam', 'tmpfile', 'touch', 'unlink', 'chdir', 'chroot', 'closedir', 'dir', 
          'getcwd', 'opendir', 'readdir', 'rewinddir', 'scandir', 'dio_close', 'dio_fcntl', 'dio_open', 'dio_read', 
          'dio_seek', 'dio_stat', 'dio_tcsetattr', 'dio_truncate', 'dio_write', 'finfo_buffer', 'finfo_close', 
          'finfo_file', 'finfo_open', 'finfo_set_flags', 'mime_content_type', 'inotify_add_watch', 'inotify_init', 
          'inotify_queue_len', 'inotify_read', 'inotify_rm_watch', 'setproctitle', 'setthreadtitle', 'xattr_get', 
          'xattr_list', 'xattr_remove', 'xattr_set', 'xattr_supported'); 

public function RunIt(){ 
    $valid = $this->CheckIt(); 
    if($valid){ 
     eval($this->Code); 
    }else{ 
     // code is invalid 
     $this->Error = 'The code in this plugin is invalid.'; 
     return null;  
    } 
} 

private function CheckIt(){ 
    $ret = false; 
    ob_start(); // Catch potential parse error messages 
    $code = eval('if(0){' . "\n" . $this->Code . "\n" . '}'); 
    ob_end_clean(); 
    $ret = ($code !== false); 
    // run a check against the dissallowed 
    $ret = (stripos($this->Code , $this->DoNotAllow) !== false); 
    // make sure any path is there's and there's alone 
    $ret = (stripos($this->Code , $this->SitePath) !== false); 
    return $ret; 
} 

} 

?> 

但沒有什麼是happenning ......其實頁面我試圖運行此在空白了(意思是有happenning錯誤)

+0

你有沒有在服務器錯誤日誌看了看被報告有什麼錯誤的? – andrewsi

+0

我有,沒有任何報告 – Kevin

+0

看看http://stackoverflow.com/questions/845021/how-to-get-useful-error-messages-in-php - 它會告訴你如何獲得錯誤消息在調試時輸出到屏幕。 – andrewsi

回答

0

你」重新生成代碼格式爲:

eval("function GetPageWeAreOn(){$p=explode('/',$_SERVER['REQUEST_URI']);return $p[1];}"); 

發生了什麼事是,PHP被錯誤解釋變量 - 而不是將它們傳遞到eval'ed功能,它的插值首先。

我已經逃離他們避免錯誤:

eval("function GetPageWeAreOn(){\$p=explode('/',\$_SERVER['REQUEST_URI']);return \$p[1];}"); 

就能避免需要把你的字符串逃脫被eval'ed成單引號,太 - 不嘗試進行插值變量:

eval('function GetPageWeAreOn(){$p=explode("/",$_SERVER["REQUEST_URI"]);return $p[1];}'); 
+0

有問題,請認真考慮這個問題(其中一些是我絆倒的問題)謝謝! – Kevin

+0

不客氣。就像這是一個非常有趣的項目! – andrewsi