【问题标题】:PHP function passing include filePHP函数传递包含文件
【发布时间】:2012-11-21 15:05:46
【问题描述】:

我正在尝试创建一个 loadPlugin(plugin) 函数,该函数将从插件文件夹中获取 php 文件并将其变量/函数加载到站点中。

问题是我们都知道函数不是全局的,这引发了我的问题。

由于可以包含任何文件,因此我无法将文件中的每个变量都设为全局变量,因为它们可以是随机的和无限的,我想将其设置为文件中的任何函数都可以在页面上的任何位置使用。

任何关于如何做到这一点的建议都会很棒。谢谢!

这是我目前所拥有的:

function loadPlugin($name,$debug='') {
    if(file_exists("scripts/plugins/".$name)) {
        include("scripts/plugins/".$name);
    } else if(strtolower($debug)=='d') trigger_error($name." does not exists in the plugins folder.", E_USER_ERROR);
}

【问题讨论】:

    标签: php html css web


    【解决方案1】:

    好吧,我遇到了类似的问题,并决定寻找可重用和可扩展的东西。 所以,我只是为了演示科林的答案而为你修剪了它。代码可以改进:)

    <?php
    /**
    * Autoloader
    * @Usage: 
    *       // set autoload paths
    *       Loader::setPaths(
    *               array("interface_path"=>dirname(__FILE__). "/core"),
    *               array("plugin_path"=>"/var/www/awesome-app/plugins"),
    *               array("controller_path"=>dirname(__FILE__). "/controllers")
    * );
    * 
    * 
    *   // Now, the magic
    *       Loader::registerAutoloads();
    */
    
    class Loader{
    
    protected static $interfacePath = '';
    protected static $pluginPath = '';
    protected static $controllerPath = '';
    
    /**
     * Set paths to autoload classes
     *
     * @param string $application
     * @param string $library
     * @todo this part can be cleaner/smarter with less code.
     *  Replace "" for with constants as default folders to search
     */
    public static function setPaths($autoload_paths= null)
    {
        if(is_array($autoload_paths)){
            self::$interfacePath = array_key_exists("interface_path", $autload_paths) ? 
                            $autoload_paths["interface_path"] : "";
    
            self::$interfacePath = array_key_exists("plugin_path", $autload_paths) ? 
                            $autoload_paths["plugin_path"] : "";
    
            self::$interfacePath = array_key_exists("controller_path", $autload_paths) ? 
                            $autoload_paths["controller_path"] : "";
    
        }       
    }
    
    
    /**
     * Registers autoload functions
     *
     */
    public static function registerAutoloads() {
        spl_autoload_register('Loader::loadInterface');
        spl_autoload_register('Loader::loadPlugin');
        spl_autoload_register('Loader::loadController');
        if ( function_exists('__autoload') ) {
            spl_autoload_register('__autoload');
        }
    }
    
    /**
     * Checks if a given file exists and load it
     *
     * @param string $filename
     * @return bool
     */
    protected static function check($filename)
    {
        if(file_exists($filename)){
             include_once $filename;
            return true;
        }
        return false;        
    }
    
    
    /**
     * Interface Loader
     *
     * @param string $className
     * @return bool
     */
    static function loadInterface($className)
    {
        return self::check(
            sprintf('%s/%s_interface.php',self::$interfacePath, low($className))
        );
    }
    
    
    /**
     * Plugin Loader
     *
     * @param string $className
     * @return bool
     */
    static function loadPlugin($className)
    {
        return self::check(
            sprintf('%s/%s_plugin.php',self::$pluginPath,low($className))
        );
    }
    
    
    
    /**
     * Controller Loader.
     *
     * @param string $className
     * @return bool
     */
    static function loadController($className){
        $fileName = camelCaseToUnderscore($className);
        return self::check(
            sprintf('%s/%s_controller.php',self::$controllerPath,$fileName)
            );
       }
    
    
     }
    
      ?>
    

    它使用 PHP 的自动加载功能,所以请确保你拥有它们。 为了解决冲突,我添加了一个修复冲突的小型注册表类(用于唯一变量和函数的键/值存储)。 它还提高了性能。 对你的工作来说可能有点过头了,但它对我很有帮助,因为我的项目相当大。

    【讨论】:

      【解决方案2】:

      您可以尝试使用以下代码创建一个名为 loadPlugin.php 的文件,而不是调用该函数:

      if( file_exists("scripts/plugins/".$name)) include("scripts/plugins/".$name));
      elseif( strtolower($debug) == "d") trigger_error("....");
      

      然后,加载插件:

      $name = "pluginName"; include("loadPlugin.php");
      

      您可以根据需要多次包含单个文件,只要它们不尝试重新定义函数即可。所以这基本上就像一个在全局范围内调用的函数。

      【讨论】:

      • 这基本上就是我现在正在做的事情。我只是想让他们更容易调用它们,并且对那些也编辑我的代码的人来说更友好。我可以将 name 设为一个数组,然后循环遍历它,每次只调用一次 loadPlugin(),有点像你在这里所说的。
      【解决方案3】:

      加载具有功能的文件似乎很不稳定。为什么不创建类并采用面向对象的方法?

      您可以加载可在整个代码中重复使用的对象。您甚至可以实现一个接口,该接口可以保证在所有插件中存在某些方法和属性,而不管它们是谁开发的。

      就“全局”而言,我可以想到几种不同的路径,您可以使用会话变量来存储每次加载新页面时填充对象的信息的持久性。甚至将对象本身存储到会话中(这不是最佳实践,但仍然可能)。

      【讨论】:

      • 总是加载我的所有功能而不是与页面相关的功能是否最好?未使用的功能会减慢页面加载速度吗?我的意思是,我认为下载具有 10 到 15 个更大功能的文件并不是那么糟糕,但我认为最好只坚持每页所需的内容。
      • PHP 代码没有发送到客户端。它呈现在服务器上。
      【解决方案4】:

      创建全局数组,例如 $pluginVars 并在插件文件内部存储所有你想在这个数组外部使用的变量。

      【讨论】:

      • 说它不是一个变量而是一个函数,你能把那个函数设为全局吗?我正在尝试更多地使用函数,因为我以前真的从未使用过它们,因为它们让我更加恼火。
      猜你喜欢
      • 1970-01-01
      • 2015-12-21
      • 2010-12-08
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      • 2013-04-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多