Магические константы из вызываемого файла - не файл действия

У меня есть эта функция в моем классе:

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
NAMESPACE:
КЛАСС: Регистратор

Мой ожидаемый результат был, что он вернется

КАТАЛОГ: /var/www/dir
ФАЙЛ: /var/www/dir/bar.php
МЕТОД:
НАЗНАЧЕНИЕ:
NAMESPACE:
УЧЕБНЫЙ КЛАСС:

Чтение документов проясняет мне, что это нормально.

Можно ли каким-то образом использовать магические константы из fileb.php в filea.php, не передавая параметры в функцию?

1 ответ

Решение

Благодаря ссылкам pos dupe мне удалось немного покопаться, чтобы действительно получить то, что я хочу. Похоже с debug_backtrace() это хорошо.. прослеживает через каждый вызов функции. Например

fileA.php

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

fileB.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)) но я не нуждался / не интересовался. Черта более или менее совпадает с __NAMESPACE__ в моем использовании, так что опять же, он не был заинтересован в создании функции для него.

Заметки:

  • Это часть класса, который я создал, который использует защищенную функцию через общедоступные функции - пожалуйста, игнорируйте:)

  • Эти функции можно очистить (например, вместо $trace = $call['file'], используйте $file в качестве параметра)

Другие вопросы по тегам