【背景】
折腾:
期间,本身已经实现了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,即可实现动态可变参数传入并打印输出格式化的字符串了。