我使用CakePHP 2.4.7和CakeDC的TinyMCE插件。
我在我的服务器上的共享位置设置了我的CakePHP核心以及插件使多个应用程序可以访问它。这使我不必更新TinyMCE的多个副本。一切正常,直到我迁移到一个新的服务器和更新的软件。
新服务器运行Apache 2.4而不是2.2,并使用mod_ruid2而不是suexec。 >
我试图加载编辑器时出现错误:
致命错误,在[/xyz/Plugin/TinyMCE/webroot/js/tiny_mce/tiny_mce.js,第1行]中出现意外的T_CONSTANT_ENCAPSED_STRING
如何开始调试?
解决方法尝试我试图从应用程序的webroot添加一个符号链接到TinyMCE的插件webroot。这是因为它加载js文件和编辑器,但后来TinyMCE插件正在错误的当前目录下工作,文件管理不会分开。
解决方案问题是 AssetDispatcher 过滤器,它包括 css 和使用PHP include()语句的js 文件,导致文件通过PHP解析器发送,
请参阅 github/.../2.4.7/lib /Cake/Routing/Filter/AssetDispatcher.php#L159-L160
这是一个很讨厌的问题,因为它是非文档和非可选的
自定义资源分配器如果您想继续使用插件资产分配器,扩展内置的,并重新实现 AssetDispatcher :: _ deliverAsset()方法,删除include功能。当然这有点恼人,维护明智,但它是一个很快的修复。
有点像:
// app / Routing / Filter / MyAssetDispatcher.php App :: uses('AssetDispatcher','Routing / Filter'); class MyAssetDispatcher extends AssetDispatcher { protected function _deliverAsset(CakeResponse $ response,$ assetFile,$ ext){ //查看您的CakePHP核心的源代码 //你需要重新实现的实际代码 ob_start(); $ compressionEnabled = Configure :: read('Assetpress')&&& $ response-> compress(); if($ response-> type($ ext)== $ ext){ $ contentType ='application / octet-stream'; $ agent = env('HTTP_USER_AGENT'); if(preg_match('%Opera(/ |)([0-9]。[0-9] {1,2})%',$ agent)|| preg_match 9]。[0-9] {1,2})/',$ agent)){ $ contentType ='application / octetstream'; } $ response-> type($ contentType); } if(!$ compressionEnabled){ $ response-> header('Content-Length',filesize($ assetFile)); } $ response-> cache(filemtime($ assetFile)); $ response-> send(); ob_clean(); //而不是原始 //方法源中可能的`include()`,使用`readfile()`只有 readfile($ assetFile ); if($ compressionEnabled){ ob_end_flush(); } } }// app / Config / bootstrap.php 配置:: write('Dispatcher.filters',array('MyAssetDispatcher',/ / instead of AssetDispatcher // ... ));
另请参阅 book.cakephp/2.0/en/development/dispatch-filters.html
不要只是禁用短打开的标签我只是猜测在这里,但它是为什么工作的原因其他服务器可能是 短打开标记 (即<?)。然而,即使这是你的新服务器上的问题,这不是你应该依赖,资产仍然使用 include(),并且你很可能不想检查所有第三方CSS / JS的每次更新可能的PHP代码注入。
I'm using CakePHP 2.4.7 and the TinyMCE plugin from CakeDC.
I set up my CakePHP core along with the plugin in a shared location on my server so that multiple applications can access it. This keeps me from having to update multiple copies of TinyMCE. Everything was working well until I migrated to a new server and updated software.
The new server is running Apache 2.4 instead of 2.2 and using mod_ruid2 instead of suexec.
I now get this error when trying to load the editor:
Fatal Error (4): syntax error, unexpected T_CONSTANT_ENCAPSED_STRING in [/xyz/Plugin/TinyMCE/webroot/js/tiny_mce/tiny_mce.js, line 1]
How should I start debugging this?
Workaround AttemptI tried adding a symlink from an application's webroot to TinyMCE's plugin webroot. This works in that it loads the js file and the editor, but then TinyMCE plugins are working on the wrong current directory and file management would not be separated.
解决方案The problem is the AssetDispatcher filter, it includes css and js files using PHPs include() statement, causing the files to be sent through the PHP parser, where it will stumble over the occurrences of <? in the TinyMCE script.
See github/.../2.4.7/lib/Cake/Routing/Filter/AssetDispatcher.php#L159-L160
A very annoying, and, since it's undocumented and non-optional, dangerous behavior if you ask me.
Custom asset dispatcherIn case you want to continue to use a plugin asset dispatcher, extend the built in one, and reimplement the AssetDispatcher::_deliverAsset() method with the include functionality removed. Of course this is kinda annoying, maintenance wise, but it's a pretty quick fix.
Something like:
// app/Routing/Filter/MyAssetDispatcher.php App::uses('AssetDispatcher', 'Routing/Filter'); class MyAssetDispatcher extends AssetDispatcher { protected function _deliverAsset(CakeResponse $response, $assetFile, $ext) { // see the source of your CakePHP core for the // actual code that you'd need to reimpelment ob_start(); $compressionEnabled = Configure::read('Assetpress') && $response->compress(); if ($response->type($ext) == $ext) { $contentType = 'application/octet-stream'; $agent = env('HTTP_USER_AGENT'); if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent) || preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) { $contentType = 'application/octetstream'; } $response->type($contentType); } if (!$compressionEnabled) { $response->header('Content-Length', filesize($assetFile)); } $response->cache(filemtime($assetFile)); $response->send(); ob_clean(); // instead of the possible `include()` in the original // methods source, use `readfile()` only readfile($assetFile); if ($compressionEnabled) { ob_end_flush(); } } }// app/Config/bootstrap.php Configure::write('Dispatcher.filters', array( 'MyAssetDispatcher', // instead of AssetDispatcher // ... ));
See also book.cakephp/2.0/en/development/dispatch-filters.html
Don't just disable short open tagsI'm just guessig here, but the reason why it was working on your other server probably is that short open tags (ie <?) where disabled. However even if that is the problem on your new server, this isn't something you should rely on, the assets are still being served using include(), and you most probably don't want to check all your third party CSS/JS for possible PHP code injections on every update.
更多推荐
在多个应用程序之间共享TinyMCE插件
发布评论