How to merge Zend Framework 2 module public direct

2019-01-23 12:47发布

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?

I would like it so that these resources were automatically available through http://mysite.com/[moduleName]/. For example,

root/public/js/sitescript.js --> http:\\mysite.com\js\sitescript.js

root/module/mymodule/public/js/modulescript.js --> http:\\mysite.com\mymodule\js\modulescript.js

root/vendor/vendormodule/public/js/vendorscript.js --> http:\\mysite.com\vendormodule\js\vendorscript.js

Should these resources be copied to the root/public directory? Manual copying will be painful, and I doubt an automated build process to merge the directories would be very practial either.

Perhaps there is some magic that can be worked with httpd.conf or .htaccess?

Perhaps symlinks are the solution? But, symlinks are not straight forward to get going on a Windows platform, and would need to be created manually for each individual module.

3条回答
Animai°情兽
2楼-- · 2019-01-23 13:30

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 :)

查看更多
可以哭但决不认输i
3楼-- · 2019-01-23 13:35

You could try using phing to manage your build process and have it automate it all. You'd have to write the build script but afterwards it would just be like hitting play on a cd player.

Of course for testing it would be a pain.

查看更多
ゆ 、 Hurt°
4楼-- · 2019-01-23 13:37

There are 4 ways of handling this:

  1. Symlinking assets in the public/ directory
  2. Copy-pasting assets from the modules to the public/ directory
  3. Using a particular Virtual Host Configuration (or generally web-server configuration)
  4. Use an asset-manager module, such as one of the following:

    • AssetManager - backed by assetic - merges assets at runtime, has caching for production environments and filters for CSS/JS minification and LESS/SASS conversion, allows exposing of assets from directories in the modules themselves.
    • zf2-assetic-module - backed by assetic - handles CSS/JS minification and LESS/SASS conversion at runtime
    • BaconAssetLoader - exposes assets from modules by deploying them in the public/ dir at deploy time
查看更多
登录 后发表回答