dongshan4878 2014-09-18 16:18
浏览 40

在codesleeve / asset-pipeline javascript中解析PHP

I'm trying to require a .js.php file in codesleeve/asset-pipeline for Laravel 4, and have not been able to get it working successfully. Has anyone else had trouble with this?

The problem...

I use gettext to feed some translation strings into JavaScript (e.g. for error messages). My javascript looks something like this (locale.js.php) where _e is an escaped string from gettext using sprint.

Locale.define('<?php echo $USER_LOCALE; ?>', 'Number' , {
  billion: '<?php echo _e('%s billion', '{x}'); ?>'
});

This all works perfectly when throwing the correct header on it and calling the file directly. It will output:

Locale.define('fr-FR', 'Number' , {
  billion: 'milliard {x}'
});

In my asset-pipeline config file, I added the extension .js.php to my javascripts mime array, and added the filter:

'filters' => array(
    '.js.php' => array(
        new AssetPipelinePHP
    ),
    ...

where the class AssetPipelinePHP is: (I know eval is dangerous, but bear with me)

class AssetPipelinePHP implements FilterInterface {
    ...
    public function filterDump(AssetInterface $asset) {
        $content = eval("?> " . $asset->getContent() . " <?php ");
        $asset->setContent($content);
    }
}

Finally, in my application.js file I have:

//= require_tree modernizr
//= require_tree mootools
//= require_tree locale

This will display the javascript correctly (though ABOVE modernizr instead of at the end of the file) for the first page load only. Consecutive page loads will not display any of the locale.js.php file. However, if I change the locale.js.php file at all (inserting a will do) then again it shows correctly for one page load.

  • 写回答

1条回答 默认 最新

  • doubo4336 2015-01-21 15:45
    关注

    From the eval documentation:

    eval() returns NULL unless return is called in the evaluated code

    So the first time you load the script it's probably just echoing the result of eval into the page, which would explain why it's rendering above modernizr. Consecutive page loads will print the cached value of the $asset content, which would be NULL as returned from eval.

    If you want to capture the output of echo you could use ob_get_contents. So your code may look like this:

    class AssetPipelinePHP implements FilterInterface {
        public function filterDump(AssetInterface $asset) {
            ob_start(); // Start output buffering
    
            eval("?> " . $asset->getContent() . " <?php ");
            $content = ob_get_contents();
    
            ob_end_clean(); // End buffering and clean up
    
            $asset->setContent($content);
        }
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能