【已解决】将Log函数的参数改变为类似于sprintf的动态个数的可变参数

【背景】

折腾:

【已解决】微信公众号开发期间申请ACCESS_TOKEN

期间,本身已经实现了log函数写入到文件了:

【已解决】PHP将log信息写入服务器中的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.貌似可以通过:

PHP: call_user_func – Manual

去实现?

3.又或者:

PHP: func_get_args – Manual

获得了参数的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

PHP: vsprintf – Manual

去试试。

    /*
        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,即可实现动态可变参数传入并打印输出格式化的字符串了。



发表评论

电子邮件地址不会被公开。 必填项已用*标注

无觅相关文章插件,快速提升流量