How to merge Zend Framework 2 module public directories

后端 未结 3 1111
傲寒
傲寒 2020-12-15 18:19

Some zf2 modules have public directories for distribution of resources such as js/css/images. What is best practice for making these resouces available to the applicaiton?

3条回答
  •  北荒
    北荒 (楼主)
    2020-12-15 18:54

    There are many ways of doing it.

    In my opinion, Assetic is a waste of computing performance, and a really bad fit for this simple problem.

    The problem, as stated, is accessing /public from modules.

    My solution is the following:

    Edit htdocs/yoursite/public/.htaccess to add this line right after RewriteEngine On:

    RewriteRule ^resource/([a-zA-Z0-9\.\-]+)/([a-zA-Z0-9\.\-_\/]+)$ index.php?action=resource&module=$1&path=$2 [QSA,L]
    

    Edit htdocs/yoursite/public/index.php and add this code right after chdir(dirname(DIR));:

    if (isset($_GET['action']) && $_GET['action'] == "resource") {
        $module = $_GET['module'];
        $path = $_GET['path'];
        if (!ctype_alnum($module))
            die("Module name must consist of only alphanumeric characters");
    
        $filetype = pathinfo($path, PATHINFO_EXTENSION);
        $mimetypes = array(
            'js' => "text/javascript",
            'css' => "text/css",
            'jpg' => "image/jpeg",
            'jpeg' => "image/jpeg",
            'png' => "image/png"
        );
    
        if (!isset($mimetypes[$filetype]))
            die(sprintf("Unrecognized file extension '%s'. Supported extensions: %s.", htmlspecialchars($filetype, ENT_QUOTES), implode(", ", array_keys($mimetypes))));
    
        $currentDir = realpath(".");
        $destination = realpath("module/$module/public/$path");
        if (!$destination)
            die(sprintf("File not found: '%s'!", htmlspecialchars("module/$module/public/$path", ENT_QUOTES)));
    
        if (substr($destination, 0, strlen($currentDir)) != $currentDir)
                die(sprintf("Access to '%s' is not allowed!", htmlspecialchars($destination, ENT_QUOTES)));
    
        header(sprintf("Content-type: %s", $mimetypes[$filetype]));
        readfile("module/$module/public/$path", FALSE);
        die();
    }
    

    Usage: /resource/moduleName/path

    Example: http://yoursite.com/resource/Statistics/css/style.css will read the actual css from yoursite/module/Statistics/public/css/style.css.

    It's fast, secure, doesn't need you to specify any paths in config, needs no installation, doesn't rely on 3rd-party maintenance, and needs no helper in view. Simply access /resource from anywhere! Enjoy :)

提交回复
热议问题