数组中的函数,
Functions in Arrays,
我正在制作一个 PHP class,它将函数存储在一个数组中,这样您就可以在任何地方重写这些函数。我面临的问题是这些函数接受 X 个参数但是当我调用它们时它发送一个包含参数的数组。
这是class
<?php
/**
* Controller Class
*
* This class will handle the controllers, it will contain an array with the
* functions that will handle each controller (I know it's a bad description but
* read the code and you'll know what I mean -.- :* ). Anyway, read the code
* I think it's big enough to make it look something cool
*
* @author Manulaiko
*/
class Controller
{
/**
* array functions
*
* It will contain the functions that will be used by the controller.
* The key of each index is a name that describes the function, don't change
* them, if you want to make a plugin, just keep same name and add a diferent
* function.
*
* The value is the function itself, it will accept an array as parameter
* that will contain the arguments, whether you want to be the array, I don't
* just make it works
*/
private $functions;
/**
* Constructor
*
* This will set the default indexes in the $functions array, you don't need
* to change anything here, this are the default functions of Alexya's core
*/
public function __construct()
{
$this->functions = array(
/**
* This is an example, it's never used
*
* You can add the functions directly here or use Controller::set()
* which accepts the key of the index as first parameter (a string)
* and the value of the index as second parameter (a function)
*
* To call this function just use Controller::load() which accepts
* a string as first parameter (in this case "test") and an array
* as second parameter (which will be the parameters of the function)
*/
"test" => function($params) {
var_dump($params);
},
/**
* Register function
*
* @see clases/Session.php
*/
"register_user" => "Session::register"
);
}
/**
* Adds an entry to the array
*
* Use this method if you want to add a function that Alexya will execute
* Use the default names if you want to override an existing function or
* use your own if not.
*
* @param string name name of the function that will be saved in the array
* @param function function the function that will be executed
*
* @return true if $name already exists and was overwrited, false if it didn't
* exist but was added properly
*/
public function __set($name, $function)
{
if(array_key_exists($name, $this->functions)) {
$this->functions[$name] = $function;
return true;
} else {
$this->functions[$name] = $function;
return false;
}
}
/**
* Executes a function
*
* This method will execute a function of the array.
*
* @param string name name of the function to execute
* @param mixed param parameters that will be passed to the function
*
* @returns true if functions exists false if not
*/
public function __call($name, $param)
{
if(!array_key_exists($name, $this->functions)) {
if(DEBUG) {
echo "Call to undefined function $name in Controller class!";
}
return false;
}
return call_user_func($this->functions[$name], $param);
}
}
我是这样称呼它的:
<?php
/**
* Index page
*
* This file will contain the behaivour of the site, everything will be here
*
* @author Manulaiko
*/
//include Alexya's Core
require_once("globConfig.php");
//Redirect user if he cant access the page
$Controller->user_can_access_website();
echo "<br/>";
$Controller->test(array(1,2,3,4,5,6,7,8,9));
echo "<br/>";
$Controller->register_user("asdfasdf", "asdfasdf", "asdfasdf@g.as");
第一次调用 Controller
没问题,因为函数 check_user_has_access
不存在于数组中显示错误。
下一次调用 $Controller->test
转储一个数组,其中包含一个包含 1
-9
.
的数组
最后一次调用发送一个包含给定参数的数组。但是,调用的函数不接受数组,而是接受这 3 个参数。
有什么办法可以解决吗?
这是我正在调用的函数:
/**
* Performs a register attempt
*
* Will try to perform a register attempt with the given username and password
* if the register succed user will be redirected to home page
*
* @param string username user's name
* @param string password text password (will be encrypted here)
* @param string mail register email
*
* @return false if register failed
*/
public function register($username, $password, $email)
{
global $Database;
global $Alexya;
/**
* Can continue, boolean
*
* If an error happened this flag will be switched to false
*/
$can_continue = true;
//check username
if(empty($username)) {
Results::addFlash(array(
"result" => "error",
"message" => "Username can't be empty!"
));
$can_continue = false;
} else if(strlen($username) < $Alexya->min_username_length) {
Results::addFlash(array(
"result" => "error",
"message" => "Username can't be shorter than $Alexya->min_username_length characters!"
));
$can_continue = false;
} else if(strlen($username) > $Alexya->max_username_length) {
Results::addFlash(array(
"result" => "error",
"message" => "Username can't be longer than $Alexya->max_username_length characters!"
));
$can_continue = false;
}
//check password
if(empty($password)) {
Results::addFlash(array(
"result" => "error",
"message" => "Password can't be empty!"
));
$can_continue = false;
} else if(strlen($password) < $Alexya->min_password_length) {
Results::addFlash(array(
"result" => "error",
"message" => "Password can't be shorter than $Alexya->min_password_length characters!"
));
$can_continue = false;
} else if(strlen($password) > $Alexya->max_password_lenght) {
Result::addFlash(array(
"result" => "error",
"message" => "Password can\'t be longer than $Alexya->max_password_lenght characters!"
));
$can_continue = false;
}
//check email
if(empty($email)) {
Results::addFlash(array(
"result" => "error",
"message" => "Email can't be empty!"
));
$can_continue = false;
} else if(preg_match("", $email)) {
Results::addFlash(array(
"result" => "error",
"message" => "The email see,s to be incorrect!"
));
$can_continue = false;
}
//Check no error ocurred
if($can_continue) {
$password = md5($password);
//check username/pass exists
$username_exists = $Database->query("SELECT * FROM accounts WHERE username='$username'");
if($username_exists && $username_exists->num_rows == 0) {
$sessionID = $Controller->generate_sessionID();
//insert user in database
$userID = $Database->insert("users", array(
"username" => $username,
"password" => $password,
"email" => $email,
"sessionID" => $sessionID
));
if(is_numeric($userID)) {
$_SESSION["sessionID"] = $sessionID;
Results::addFlash(array(
"result" => "success",
"message" => "You're now registered!"
));
Functions::redirect(URL."?page=home");
} else {
Results::addFlash(array(
"result" => "error",
"message" => "Couldn't add user to database!"
));
}
} else {
Results::addFlash(array(
"result" => "error",
"message" => "Wrong username/password, please try again!"
));
}
}
return false;
}
编辑:这是输出:
Call to undefined function user_can_access_website in Controller class!<br />
<b>Warning</b>: Missing argument 2 for Session::register() in <b>/home/cabox/workspace/classes/Session.php</b> on line <b>126</b><br />
<br />
<b>Warning</b>: Missing argument 3 for Session::register() in <b>/home/cabox/workspace/classes/Session.php</b> on line <b>126</b><br />
<br />
<b>Warning</b>: strlen() expects parameter 1 to be string, array given in <b>/home/cabox/workspace/classes/Session.php</b> on line <b>145</b><br />
<br />
<b>Warning</b>: strlen() expects parameter 1 to be string, array given in <b>/home/cabox/workspace/classes/Session.php</b> on line <b>151</b><br />
<br />
array(2) {
[0]=>
string(4) "test"
[1]=>
array(1) {
[0]=>
array(9) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
[7]=>
int(8)
[8]=>
int(9)
}
}
}
编辑 2:使用函数 call_user_func_array
并添加一些调试行,这就是我在调用 "test" 函数时所拥有的:
__call function:
name = test
parameters:
array(1) {
[0]=>
array(9) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
[7]=>
int(8)
[8]=>
int(9)
}
}
test function: string(4) "test"
如您所见,现在它不发送包含参数的数组,它现在发送 __call 函数
中发送的数组中的第一个参数
好的,我找到问题了。
调用该函数的代码是这样的:
/**
* Executes a function
*
* This method will execute a function of the array.
*
* @param string name name of the function to execute
* @param mixed param parameters that will be passed to the function
*
* @returns true if functions exists false if not
*/
public function __call($name, $param)
{
if(!array_key_exists($name, $this->functions)) {
if(DEBUG) {
echo "Call to undefined function $name in Controller class!";
}
return false;
}
return call_user_func($this->functions[$name], $param);
}
行
return call_user_func($this->functions[$name], $param);
正在发送一个数组作为参数,该数组包含来自 __call
函数的给定参数。
要解决此问题,@deceze 告诉我改用 call_user_func_array(string, array)
函数。
我的错误是我是这样使用它的:
return call_user_func_array($this->functions[$name], func_get_args());
代码发送的是魔术方法 __call
的参数,而不是数组 $param
中给定的参数。为了解决这个问题,我将 func_get_args()
更改为 $param
,因此该行看起来像这样:
return call_user_func_array($this->functions[$name], $param);
希望有人觉得有用
我正在制作一个 PHP class,它将函数存储在一个数组中,这样您就可以在任何地方重写这些函数。我面临的问题是这些函数接受 X 个参数但是当我调用它们时它发送一个包含参数的数组。
这是class
<?php
/**
* Controller Class
*
* This class will handle the controllers, it will contain an array with the
* functions that will handle each controller (I know it's a bad description but
* read the code and you'll know what I mean -.- :* ). Anyway, read the code
* I think it's big enough to make it look something cool
*
* @author Manulaiko
*/
class Controller
{
/**
* array functions
*
* It will contain the functions that will be used by the controller.
* The key of each index is a name that describes the function, don't change
* them, if you want to make a plugin, just keep same name and add a diferent
* function.
*
* The value is the function itself, it will accept an array as parameter
* that will contain the arguments, whether you want to be the array, I don't
* just make it works
*/
private $functions;
/**
* Constructor
*
* This will set the default indexes in the $functions array, you don't need
* to change anything here, this are the default functions of Alexya's core
*/
public function __construct()
{
$this->functions = array(
/**
* This is an example, it's never used
*
* You can add the functions directly here or use Controller::set()
* which accepts the key of the index as first parameter (a string)
* and the value of the index as second parameter (a function)
*
* To call this function just use Controller::load() which accepts
* a string as first parameter (in this case "test") and an array
* as second parameter (which will be the parameters of the function)
*/
"test" => function($params) {
var_dump($params);
},
/**
* Register function
*
* @see clases/Session.php
*/
"register_user" => "Session::register"
);
}
/**
* Adds an entry to the array
*
* Use this method if you want to add a function that Alexya will execute
* Use the default names if you want to override an existing function or
* use your own if not.
*
* @param string name name of the function that will be saved in the array
* @param function function the function that will be executed
*
* @return true if $name already exists and was overwrited, false if it didn't
* exist but was added properly
*/
public function __set($name, $function)
{
if(array_key_exists($name, $this->functions)) {
$this->functions[$name] = $function;
return true;
} else {
$this->functions[$name] = $function;
return false;
}
}
/**
* Executes a function
*
* This method will execute a function of the array.
*
* @param string name name of the function to execute
* @param mixed param parameters that will be passed to the function
*
* @returns true if functions exists false if not
*/
public function __call($name, $param)
{
if(!array_key_exists($name, $this->functions)) {
if(DEBUG) {
echo "Call to undefined function $name in Controller class!";
}
return false;
}
return call_user_func($this->functions[$name], $param);
}
}
我是这样称呼它的:
<?php
/**
* Index page
*
* This file will contain the behaivour of the site, everything will be here
*
* @author Manulaiko
*/
//include Alexya's Core
require_once("globConfig.php");
//Redirect user if he cant access the page
$Controller->user_can_access_website();
echo "<br/>";
$Controller->test(array(1,2,3,4,5,6,7,8,9));
echo "<br/>";
$Controller->register_user("asdfasdf", "asdfasdf", "asdfasdf@g.as");
第一次调用 Controller
没问题,因为函数 check_user_has_access
不存在于数组中显示错误。
下一次调用 $Controller->test
转储一个数组,其中包含一个包含 1
-9
.
最后一次调用发送一个包含给定参数的数组。但是,调用的函数不接受数组,而是接受这 3 个参数。
有什么办法可以解决吗?
这是我正在调用的函数:
/**
* Performs a register attempt
*
* Will try to perform a register attempt with the given username and password
* if the register succed user will be redirected to home page
*
* @param string username user's name
* @param string password text password (will be encrypted here)
* @param string mail register email
*
* @return false if register failed
*/
public function register($username, $password, $email)
{
global $Database;
global $Alexya;
/**
* Can continue, boolean
*
* If an error happened this flag will be switched to false
*/
$can_continue = true;
//check username
if(empty($username)) {
Results::addFlash(array(
"result" => "error",
"message" => "Username can't be empty!"
));
$can_continue = false;
} else if(strlen($username) < $Alexya->min_username_length) {
Results::addFlash(array(
"result" => "error",
"message" => "Username can't be shorter than $Alexya->min_username_length characters!"
));
$can_continue = false;
} else if(strlen($username) > $Alexya->max_username_length) {
Results::addFlash(array(
"result" => "error",
"message" => "Username can't be longer than $Alexya->max_username_length characters!"
));
$can_continue = false;
}
//check password
if(empty($password)) {
Results::addFlash(array(
"result" => "error",
"message" => "Password can't be empty!"
));
$can_continue = false;
} else if(strlen($password) < $Alexya->min_password_length) {
Results::addFlash(array(
"result" => "error",
"message" => "Password can't be shorter than $Alexya->min_password_length characters!"
));
$can_continue = false;
} else if(strlen($password) > $Alexya->max_password_lenght) {
Result::addFlash(array(
"result" => "error",
"message" => "Password can\'t be longer than $Alexya->max_password_lenght characters!"
));
$can_continue = false;
}
//check email
if(empty($email)) {
Results::addFlash(array(
"result" => "error",
"message" => "Email can't be empty!"
));
$can_continue = false;
} else if(preg_match("", $email)) {
Results::addFlash(array(
"result" => "error",
"message" => "The email see,s to be incorrect!"
));
$can_continue = false;
}
//Check no error ocurred
if($can_continue) {
$password = md5($password);
//check username/pass exists
$username_exists = $Database->query("SELECT * FROM accounts WHERE username='$username'");
if($username_exists && $username_exists->num_rows == 0) {
$sessionID = $Controller->generate_sessionID();
//insert user in database
$userID = $Database->insert("users", array(
"username" => $username,
"password" => $password,
"email" => $email,
"sessionID" => $sessionID
));
if(is_numeric($userID)) {
$_SESSION["sessionID"] = $sessionID;
Results::addFlash(array(
"result" => "success",
"message" => "You're now registered!"
));
Functions::redirect(URL."?page=home");
} else {
Results::addFlash(array(
"result" => "error",
"message" => "Couldn't add user to database!"
));
}
} else {
Results::addFlash(array(
"result" => "error",
"message" => "Wrong username/password, please try again!"
));
}
}
return false;
}
编辑:这是输出:
Call to undefined function user_can_access_website in Controller class!<br />
<b>Warning</b>: Missing argument 2 for Session::register() in <b>/home/cabox/workspace/classes/Session.php</b> on line <b>126</b><br />
<br />
<b>Warning</b>: Missing argument 3 for Session::register() in <b>/home/cabox/workspace/classes/Session.php</b> on line <b>126</b><br />
<br />
<b>Warning</b>: strlen() expects parameter 1 to be string, array given in <b>/home/cabox/workspace/classes/Session.php</b> on line <b>145</b><br />
<br />
<b>Warning</b>: strlen() expects parameter 1 to be string, array given in <b>/home/cabox/workspace/classes/Session.php</b> on line <b>151</b><br />
<br />
array(2) {
[0]=>
string(4) "test"
[1]=>
array(1) {
[0]=>
array(9) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
[7]=>
int(8)
[8]=>
int(9)
}
}
}
编辑 2:使用函数 call_user_func_array
并添加一些调试行,这就是我在调用 "test" 函数时所拥有的:
__call function:
name = test
parameters:
array(1) {
[0]=>
array(9) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
[7]=>
int(8)
[8]=>
int(9)
}
}
test function: string(4) "test"
如您所见,现在它不发送包含参数的数组,它现在发送 __call 函数
中发送的数组中的第一个参数好的,我找到问题了。
调用该函数的代码是这样的:
/**
* Executes a function
*
* This method will execute a function of the array.
*
* @param string name name of the function to execute
* @param mixed param parameters that will be passed to the function
*
* @returns true if functions exists false if not
*/
public function __call($name, $param)
{
if(!array_key_exists($name, $this->functions)) {
if(DEBUG) {
echo "Call to undefined function $name in Controller class!";
}
return false;
}
return call_user_func($this->functions[$name], $param);
}
行
return call_user_func($this->functions[$name], $param);
正在发送一个数组作为参数,该数组包含来自 __call
函数的给定参数。
要解决此问题,@deceze 告诉我改用 call_user_func_array(string, array)
函数。
我的错误是我是这样使用它的:
return call_user_func_array($this->functions[$name], func_get_args());
代码发送的是魔术方法 __call
的参数,而不是数组 $param
中给定的参数。为了解决这个问题,我将 func_get_args()
更改为 $param
,因此该行看起来像这样:
return call_user_func_array($this->functions[$name], $param);
希望有人觉得有用