Nano Hash - криптовалюты, майнинг, программирование

PHP: получить контекст производного класса в статической функции? т.е. различаются между BaseClass::staticBaseFunc() и DerivedClass::staticBaseFunc()

У меня есть базовый класс со статической функцией. Но я хотел бы иметь способ узнать фактический класс (может быть базовый класс или производный класс), в контексте которого я вызываю статическую функцию.

Например:

<?php

class Foo
{
    static function Test() 
    { 
        $c = self::class;
        echo "Hello, I am creating a new instance of type $c";
        return new $c;
    }
}

class Bar extends Foo 
{
    public $someProperty;
}

$b = Bar::Test(); // This should do something different than Foo::Test();

?>

Обратите внимание, что self::class в функции Test() всегда приводит к 'Foo', даже если я вызываю ее, используя контекст Bar::.

Я понимаю, что могу переопределить функцию Test() в Bar, но это не то, чего я хочу, я хочу сохранить реализованную функциональность в базовой функции Test(). Но только с фактическим контекстом статического класса, с которым я его вызываю.

Есть ли способ для приведенной выше функции Test() сказать: «Я создаю новый экземпляр типа Bar» и вернуть экземпляр Bar, а не Foo?


  • Прочтите об экземпляре. 05.12.2019
  • @MarkusZeller Спасибо, я знал о instanceof, однако, если я не понял неправильно, это относится только к экземплярам (т.е. объектам), тогда как я вызываю функцию статического класса (т.е. не объект). 05.12.2019

Ответы:


1

Позвольте мне познакомить вас с поздним статическим связыванием.

Рассмотрим следующий код, он не совсем похож на ваш, но он подчеркивает проблему, с которой, как мне кажется, вы столкнулись.

<?php

class A 
{

    public static $string = 'I am from class A';

    public static function getString()
    {
        return self::$string;
    }
}

class B extends A
{
    public static $string = 'I am from class B';
}

B::getString(); // returns 'I am from class A' ???!
?>

Чтобы обойти это, вы можете использовать позднюю статическую привязку, чтобы использовать переменную в контексте времени выполнения (а не в контексте времени компиляции).

<?php

class A 
{

    public static $string = 'I am from class A';

    public static function getString()
    {
        return static::$string; // note the change here
    }
}

class B extends A
{
    public static $string = 'I am from class B';
}

B::getString(); // returns 'I am from class B' and all is well 
?>

Гораздо больше информации, чем я могу вам дать, доступно здесь: https://www.php.net/manual/en/language.oop5.late-static-bindings.php

05.12.2019
  • Надеюсь, я понял вашу проблему ????, я чувствую, что не понял! 05.12.2019
  • Спасибо, я знаком с концепцией позднего статического связывания, но не знал, как это работает в php. Ссылка в вашем комментарии содержала как раз то, что мне было нужно: внутри функции Foo::Test() вместо self::class мне пришлось использовать get_called_class() (manual) и теперь все работает именно так, как задумано! Вызов Foo::Test() создаст Foo, вызов Bar::Test() создаст Bar! ???? 05.12.2019
  • Блестящие вещи 05.12.2019
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..