0

我在课堂上有这个功能:

logMagic($mode)
{
    # mode
    # 1 = all, 2 = dir, 3 = file etc.

    # this is wrapped inside a switch statement
    # for eases sake here's the case 1: code
    $log['dir'] = 'DIRECTORY: '. __DIR__;
    $log['file'] = 'FILE: '. __FILE__;
    $log['meth'] = 'METHOD: '. __METHOD__;
    $log['fnc'] = 'FUNCTION: '. __FUNCTION__;
    $log['ns'] = 'NAMESPACE: '. __NAMESPACE__;
    $log['cl'] = 'CLASS: '. __CLASS__;

    return $log;
}

这是在 foo.php 文件中。然后我有一个 bar.php 文件,我在其中调用并初始化类以使用此函数:

require_once 'foo.php';

$logger = new \Logger('trey.log', 'var/logs');
$logger->logMagic($logger::ALL);

我的问题是,这将输出(在日志文件中):

目录:/var/www/dir
文件:/var/www/dir/foo.php
方法:Logger::logMagic
功能:logMagic 名称空间

类:Logger

我的预期输出是它会返回

目录:/var/www/dir
文件:/var/www/dir/bar.php
方法:
功能:
命名空间:
类:

阅读文档确实向我澄清了这一点,这是正常的。

有什么方法可以在 filea.php 中使用来自 fileb.php 的魔术常量,而不将参数传递给函数?

4

1 回答 1

0

感谢 pos dupe 链接,我设法进行了一些挖掘以真正得到我想要的东西。它似乎debug_backtrace()很好.. 追溯每个函数调用。例如

文件A.php

class Bar
{
    public function foo()
    {
        echo '<pre>'. print_r(debug_backtrace(), 1) .'</pre>';
        return 'hi';
    } 
}

文件B.php

require_once 'fileA.php';

$bar = new \Bar();
echo $bar->foo();

这输出:

Array
(
    [0] => Array
    (
        [file] => /var/www/testing/test/fileB.php
        [line] => 5
        [function] => foo
        [class] => Bar
        [object] => Bar Object ()
        [type] => ->
        [args] => Array ()
    )
)

hi

这在很大程度上是完美的。但是,这并不能保证结果,因为数组每个堆栈都会增加。

例如 FileC.php 调用 FileB.php 中的函数,后者又调用 FileA.php 中的函数

但是,我在使用函数时注意到,最理想的函数是数组中的结束元素。考虑到这一点,我设置了一些函数来模拟魔法常数的功能,而不使用任何魔法。

设置使用功能:

$trace = debug_backtrace();
$call = end($trace);

目录 ( __DIR__):

# $trace = $call['file']
protected function getDir($trace)
{
    $arr = explode('/', $trace);
    $file = end($arr);

    $directory = [];
    $i = 0;

    foreach ($arr as $data)
    {
        if ($data !== $file) {
            $directory[] = isset($output) ? $output[$i - 1] . '/' . $data : $data;
            $i++;
        }
    }

    return 'DIRECTORY: '. implode('/', $directory);
}

文件 ( __FILE__)::

# $trace = $call['file']
protected function getFile($trace)
{
    $arr = explode('/', $trace);
    $file = end($arr);

    return 'FILE: '. $file;
}

函数/方法 ( __FUNCTION__|| __METHOD__)::

# $trace = $call
protected function getFunction($trace)
{
    $output = 'FUNCTION: '. $trace['function'] ."\n";

    foreach ($trace['args'] as $key => $arguments)
    {
        foreach ($arguments as $k => $arg)
        {
            if (!is_array($arg)) {
                $output .= 'ARGS ('. $k .'): '. $arg ."\n";
            }
        }
    }

    return $output;
}

命名空间 ( __NAMESPACE__):

# $trace = $call['class']
protected function getNamespace($trace)
{
    $arr = explode('\\', $trace);
    $class = end($arr);

    $namespace = [];
    $i = 0;

    foreach ($arr as $data)
    {
        if ($data !== $class) {
            $namespace[] = isset($output) ? $output[$i - 1] . '/' . $data : $data;
            $i++;
        }
    }

    return 'NAMESPACE: '. implode('\\', $namespace);
}

类(__CLASS__):

# $trace = $call['class']
protected function logClass($trace)
{
    if (strpos($trace, '\\') !== false) {
        $arr = explode('\\', $trace);
        $class = end($arr);
    } else {
        $class = $trace;
    }

    $return = 'CLASS: '. $class;
}

缺少魔法常数:

  • __LINE__
  • __TRAIT__

线路是可访问的(正如您从 中看到的那样print_r($call, 1)),但我不需要/不感兴趣。Trait 或多或少与__NAMESPACE__我的用途相同,因此,它对为其创建函数也不感兴趣。

笔记:

  • 这是我通过公共可访问函数使用受保护函数的类的一部分 - 请忽略:)

  • 这些函数可以被清理(例如,代替 $trace = $call['file'],使用 $file 作为参数)

于 2019-01-25T16:11:20.513 回答