【背景】
折腾:
期间,本身已经实现了log函数写入到文件了:
但是在使用期间发现,其实希望更进一步的,支持这种写法的:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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,类似于:
1 2 3 4 | 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
去试试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /* 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
去试试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /* 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 />" ; } ...... } |
调用:
1 2 | $crifanLib = new crifanLib(); $crifanLib ->logWrite( "str1=%s,num1=%d" , "hello crifan" , 123); |
正常输出了:
1 2 3 4 | arguments: 3 Argument 0 = str1=%s,num1=%d Argument 1 = hello crifan Argument 2 = 123 |
9.接着是去:
【已解决】PHP中去掉数组的第一个元素获取余下所有元素作为新数组
【总结】
最后实现了所需要的效果:
crifanLib.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | 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); } } |
然后去调用:
1 2 3 4 | 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,即可实现动态可变参数传入并打印输出格式化的字符串了。