【背景】
折腾:
期间,本身已经实现了log函数写入到文件了:
但是在使用期间发现,其实希望更进一步的,支持这种写法的:
include_once "crifanLib.php";
//global definition
// define("TOKEN", "didaosuzhou");
define("APPID", "xxx"); //18 characters
// define("EncodingAESKey", "xxx"); //43 characters
define("APPSECRET", "xxx"); //32 characters
$crifanLib = new crifanLib();
// $crifanLib->logWrite("This is crifanLib log test message not pass log file name");
$tokenUrlPattern = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
$getTokenUrl = sprintf($tokenUrlPattern, APPID, APPSECRET);
$crifanLib->logWrite("getTokenUrl=%s", $getTokenUrl);即:
logWrite变成类似于sprintf那种,支持动态个数参数,可变参数。
并且,logWrite的内部实现希望是使用到sprintf,类似于:
function logWrite(arg1, arg2, ...){
formatedStr = sprintf(ar1, arg2, ..);
.....
}【折腾过程】
1.搜:
php function dynamic param
参考:
PHP: Function arguments – Manual – Variable-length argument lists
“PHP has support for variable-length argument lists in user-defined functions. This is implemented using the … token in PHP 5.6 and later, and using the func_num_args(), func_get_arg(), and func_get_args() functions in PHP 5.5 and earlier. ”
看了官网解释,虽然是支持可变个数的参数,但是貌似对于此处我的PHP 5.4来说,只能用:
func_num_args(), func_get_arg() and func_get_args().
好像就没法很方便的把参数传递到最终的sprintf中了啊。。
2.貌似可以通过:
去实现?
3.又或者:
获得了参数的list,然后传递给sprintf,就可以了?
4.看到:
php – call_user_func with dynamic parameters – Stack Overflow
->
PHP: call_user_func_array – Manual
好像说是可以用:call_user_func_array,去这样处理的。
5.那就去试试:
结果想到:sprintf是系统函数,不用用户自定义函数,所以没法用call_user_func或call_user_func_array。
6.然后想到,是否有sprintf的参数是array的版本的函数?
搜:
php sprintf array
参考:
php – printf/sprintf with array arguments instead of variables – Stack Overflow
php sprintf with array – Stack Overflow
去试试。
/*
Write log info to file
*/
function logWrite($logFormat, $logArgs = null) {
$logFormatedContent = vsprintf($logFormat, $logArgs);
// define script name
$scriptName = pathinfo($_SERVER['PHP_SELF'], PATHINFO_FILENAME);
// define current time and suppress E_WARNING if using the system TZ settings
// (don't forget to set the INI setting date.timezone)
$timeStr = @date('[Y-m-d H:i:s]');
// write current time, script name and message to the log file
//[2015-07-27 13:11:03] (wx_access_token) This is crifanLib log test
file_put_contents($this->logFile, "$timeStr ($scriptName) $logFormatedContent" . PHP_EOL, FILE_APPEND);
}
$crifanLib = new crifanLib();
// $crifanLib->logWrite("This is crifanLib log test message not pass log file name");
$tokenUrlPattern = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
$getTokenUrl = sprintf($tokenUrlPattern, APPID, APPSECRET);
$crifanLib->logWrite("getTokenUrl=%s", $getTokenUrl);
7.然后继续去试试。
期间遇到了,PHP代码出错,无任何输出的问题:
【已解决】PHP代码尝试使用vsprintf期间出错无任何输出
8.然后继续搜:
php function variable params
参考:
PHP: Define function with variable parameter count? – Stack Overflow
去试试:
/*
Write log info to file
*/
//function logWrite($logFormat, $logArgs = []) { //also OK
function logWrite($logFormat, $logArgs = array()) {
echo "Into logWrite"."<br />";
print("logFormat=".$logFormat."<br />");
print("logArgs=".$logArgs."<br />");
echo "Number of arguments: " . func_num_args() . "<br />";
for($i = 0 ; $i < func_num_args(); $i++) {
echo "Argument $i = " . func_get_arg($i) . "<br />";
}
......
}调用:
$crifanLib = new crifanLib();
$crifanLib->logWrite("str1=%s,num1=%d", "hello crifan", 123);正常输出了:
arguments: 3 Argument 0 = str1=%s,num1=%d Argument 1 = hello crifan Argument 2 = 123
9.接着是去:
【已解决】PHP中去掉数组的第一个元素获取余下所有元素作为新数组
【总结】
最后实现了所需要的效果:
crifanLib.php
class crifanLib {
private $logFile;
function __construct() {
$this->logInit();
}
/***********************************************************************************************
* Log
***********************************************************************************************/
/*
Init log file
*/
function logInit($inputLogFile = null) {
// set default log file name, path is current php file
//logFolder=/var/www/1.2.3.4/public_html/php/access_token
$logFolder = getcwd();
//logFilename=log_20150727131103.log
$logFilename = "log_".date('YmdHis').".log";
//defautLogFile=/var/www/1.2.3.4/public_html/php/access_token/log_20150727131103.log
$defautLogFile = $this->concatenatePath($logFolder, $logFilename);
$this->logFile = $inputLogFile ? $inputLogFile : $defautLogFile;
}
/*
Write log info to file
*/
//function logWrite($logFormat, $logArgs = []) { //also OK
// function logWrite($logFormat, $logArgs = array()) {
function logWrite() {
// echo "Into logWrite"."<br />";
// print("logFormat=".$logFormat."<br />");
// print("logArgs=".$logArgs."<br />");
// echo "Number of arguments: " . func_num_args() . "<br />";
// for($i = 0 ; $i < func_num_args(); $i++) {
// echo "Argument $i = " . func_get_arg($i) . "<br />";
// }
$logArgList = func_get_args();
// print_r("logArgList=".$logArgList."<br />");
$logArgFirst = array_shift($logArgList);
// print_r("logArgFirst=".$logArgFirst."<br />");
// print_r("remaing logArgList=".$logArgList."<br />");
$logFormat = $logArgFirst;
$logArgs = $logArgList;
$logFormatedContent = vsprintf($logFormat, $logArgs);
// print_r("logFormatedContent=".$logFormatedContent."<br />");
// define script name
$phpSelfFilename = pathinfo($_SERVER['PHP_SELF'], PATHINFO_FILENAME);
// define current time and suppress E_WARNING if using the system TZ settings
// (don't forget to set the INI setting date.timezone)
$curTimeStr = @date('[Y-m-d H:i:s]');
// write current time, script name and message to the log file
//[2015-07-27 13:11:03] (wx_access_token) This is crifanLib log test
file_put_contents($this->logFile, "$curTimeStr ($phpSelfFilename) $logFormatedContent" . PHP_EOL, FILE_APPEND);
}
}然后去调用:
include_once "crifanLib.php";
$crifanLib = new crifanLib();
$crifanLib->logWrite("str1=%s,num1=%d", "hello crifan", 123);即可实现:
将动态的可变的参数:
"str1=%s,num1=%d", "hello crifan", 123
传入logWrite,而logWrite中func_get_args()获得对应的参数列表,然后array_shift去pop出第一个,即format,余下作为新数组参数列表,然后再传入vsprintf,即可实现动态可变参数传入并打印输出格式化的字符串了。