在PHP中打印可调用的名称或定义

时间:2015-12-17 00:17:13

标签: php callable

PHP中的Callables可以有很多形式,比如对象,数组或包含函数名的字符串。

如果我在变量中得到这样的可调用内容,我该如何打印一些用户友好的"定义"它在日志中。

想想这段代码:

SELECT
c.company, 
c.email,
-- Using date put some condtions like >,< or extarct year and compare
DECODE(p.date_of_payment, '2014',SUM(o.total_value),0) AS ttl_order_value_2014,
Decode(p.date_of_payment,'2014' ,COUNT(p.order_id),0) AS ttl_order_count_2014,

DECODE(p.date_of_payment, '2015',SUM(o.total_value),0) AS ttl_order_value_2015,
Decode(p.date_of_payment,'2015' ,COUNT(p.order_id),0) AS ttl_order_count_2015,

FROM merch_orders_ist AS o
  INNER JOIN contacts_ern AS c
    ON (o.contact_id = c.contactid)
  INNER JOIN merch_payments_ist AS p
    ON (o.id = p.order_id)
WHERE DATE(p.date_of_payment) BETWEEN '2014-01-01' AND '2014-12-31' 
GROUP BY c.contactid 
ORDER BY ttl_order_value DESC

问题是,这会引发错误,例如数组到字符串转换错误。打印出有关可调用内容的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

这样的事情应该有效:

function getCallableName($callable) {
    if (is_string($callable)) {
        return trim($callable);
    } else if (is_array($callable)) {
        if (is_object($callable[0])) {
            return sprintf("%s::%s", get_class($callable[0]), trim($callable[1]));
        } else {
            return sprintf("%s::%s", trim($callable[0]), trim($callable[1]));
        }
    } else if ($callable instanceof Closure) {
        return 'closure';
    } else {
        return 'unknown';
    }
}

答案 1 :(得分:0)

很老的问题,但由于我只是用它来记录一些信息,我认为它可以使用一些说明。

@Fabian Picone 的评论有点误导。

类型提示实际上适用于字符串(数组也是如此),但字符串必须是现有的方法或函数(如果您在代码中添加 function foo() {} 它将起作用)。也就是说,它实际上必须是可调用的。错误消息并不那么直观。

也看到这个答案https://stackoverflow.com/a/63289789/7409925

这是我用于日志记录(从@Seb 扩展)、添加对可调用项的支持并删除不必要的 trim 的看法:

function getCallableName(callable $callable) {
    switch (true) {
        case is_string($callable) && strpos($callable, '::'):
            return '[static] ' . $callable;
        case is_string($callable):
            return '[function] ' . $callable;
        case is_array($callable) && is_object($callable[0]):
            return '[method] ' . get_class($callable[0])  . '->' . $callable[1];
        case is_array($callable):
            return '[static] ' . $callable[0]  . '::' . $callable[1];
        case $callable instanceof Closure:
            return '[closure]';
        case is_object($callable):
            return '[invokable] ' . get_class($callable);
        default:
            return '[unknown]';
    }
}