2012-12-04 64 views
2

我試圖做一個loadPlugin(插件)函數,該函數將從插件文件夾中獲取php文件並將其變量/函數加載到該網站中。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); 
} 

回答

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的自動加載功能,所以請確保你有他們。 爲了解決衝突,我添加了一個修復衝突的小型註冊表類(用於唯一變量和函數的鍵/值存儲)。 它也改善了性能。 可能對你的工作有點矯枉過正,但它對我有幫助,因爲我的項目很大。

+0

感謝您的插件。 :-) –

1

而不是調用的功能,你可以嘗試做一個名爲loadPlugin.php文件,使用此代碼:

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

然後,加載插件:

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

您可以隨意多次包含單個文件,就像只要他們不試圖重新定義職能。所以這基本上就像在全局範圍內調用的函數一樣工作。

+0

這就是我現在正在做的事情。我只是想讓它更容易打電話給他們,並且對編輯我的代碼的人更友好。我可以命名一個數組,然後遍歷它只調用一次loadPlugin(),就像你在這裏說的那樣。 –

0

創建全局數組,例如$ pluginVars和內部插件文件存儲所有變量您想在此數組中使用外部。

+0

說它不是一個變量,而是一個函數,你可以使該函數是全局的嗎?我試圖更多地使用函數,因爲我之前從來沒有用過它們,因爲它們使這類事情變得更糟。 –

+0

函數將起作用。 – Gustek

1

加載一個文件,其中的功能似乎不可靠。你爲什麼不創建類並採取面向對象的方法?

您可以加載可在整個代碼中重複使用的對象。您甚至可以實現一個接口,以確保所有插件中存在某些方法和屬性,而不管開發人員是誰。

就「全局」而言,我可以考慮幾條不同的路徑,您可以考慮使用會話變量來存儲用於在每次加載新頁面時填充對象的信息的持久性。甚至可以將對象本身存儲到會話中(這不是最佳實踐,但仍然可行)。

+0

只是最好始終加載我所有的功能,而不是與頁面相關的功能?做未使用的功能減慢頁面加載等?我的意思是我沒有看到下載文件10-15更大的功能是壞,但我想這將是更好地堅持我需要每頁只什麼。 –

+0

PHP代碼不會被髮送到客戶端。它在服務器上呈現。 –