За последние 24 часа нас посетили 22636 программистов и 1022 робота. Сейчас ищут 703 программиста ...

Как решается данная проблема

Тема в разделе "PHP для новичков", создана пользователем AlexandrS, 8 дек 2019.

  1. AlexandrS

    AlexandrS Активный пользователь

    С нами с:
    30 сен 2017
    Сообщения:
    659
    Симпатии:
    103
    Адрес:
    Краснодар
    PHP:
    1. <?php
    2.  
    3. namespace framework;
    4.  
    5. use framework\Foo\Foo;
    6.  
    7. class ClassName
    8. {
    9.     public function test($className)
    10.     {
    11.         new $className;
    12.     }
    13.  
    14. }  
    15.  
    16. ?>
    Если передать в метод 'test' какое-то значение для создание экземпляра класса
    PHP:
    1. $this->test('foo');
    Вылазит ошибка, что такого класса не существует.
    Но если прописать имя класса вручную, внутри метода т.е.
    PHP:
    1.     public function test($className)
    2.     {
    3.         new Foo;
    4.     }
    То всё отрабатывает нормально. Кроме этого будет отрабатывать нормально если указывать полный путь к расположению файла класса т.е. вот так:

    PHP:
    1.     public function test($className)
    2.     {
    3.        $path = 'framework\Foo\\'.$className;
    4.         new $path;
    5.     }
    И как бы постоянно передавать путь, ну как бы не очень красиво получается.

    PS: нашел подобный вопрос тут на форуме: https://php.ru/forum/threads/namesp...et-podkljuchenie-klassov-iz-peremennoj.58286/

    Выходит только полный путь, либо делать какой-то массив для ассоциаций, в который будет улетать короткое имя, от туда будет браться полный путь и подставляться, т.к. какой-то велосипед :(
     
    #1 AlexandrS, 8 дек 2019
    Последнее редактирование: 8 дек 2019
  2. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.822
    Симпатии:
    736
    Адрес:
    Татарстан
    имхо это все в автолоадере нужно прописать и все
     
    AlexandrS нравится это.
  3. AlexandrS

    AlexandrS Активный пользователь

    С нами с:
    30 сен 2017
    Сообщения:
    659
    Симпатии:
    103
    Адрес:
    Краснодар
    Я так понял, что если всё это генерится через композер, то как раз таки нужно именно в json файле композера это всё прописать?
     
  4. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.745
    Симпатии:
    1.319
    Адрес:
    Лень
    framework\Foo\Foo\foo :: class
     
    AlexandrS нравится это.
  5. AlexandrS

    AlexandrS Активный пользователь

    С нами с:
    30 сен 2017
    Сообщения:
    659
    Симпатии:
    103
    Адрес:
    Краснодар
    Не понял, к чему это и куда прописать?
    --- Добавлено ---
    Пробовал с композером разобраться, но что-то либо я что-то не понимаю и соответственно делаю не так и оно не работает, либо оно через него и не должно работать, хотя я больше склоняюсь к первому, что я что-то не то делаю.
     
  6. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.236
    Адрес:
    там-сям
    Ну молодец же! Всё нашёл, что надо. Да, когда имя класса в переменной, то неймспейс из use не подклеивается к имени класса, поэтому надо указывать имя вместе с неймспейсом.

    Или, можно извернуться и сделать алиасы для классов, видимо это типа как ты хотел "массив для ассоциаций", только оно тебе зачем?! Просто пойми как классы используются и не наступай на грабли.
     
    AlexandrS нравится это.
  7. AlexandrS

    AlexandrS Активный пользователь

    С нами с:
    30 сен 2017
    Сообщения:
    659
    Симпатии:
    103
    Адрес:
    Краснодар
    Решил сделать вот так:


    PHP:
    1.     private function classNames($className)
    2.     {
    3.         $classNames = [
    4.                         'Foo'=>'framework\Foo\Foo',
    5.                         'Bar'=>'framework\Bar\Bar'
    6.                       ];
    7.  
    8.         return $classNames[$className];
    9.     }
    Так как есть наследники, я решил что проще все пути указать в родителе, а в дочерних просто обращаться по имени. Так будет даже удобнее если вдруг структура изменится, тогда будет достаточно просто изменить в родителе пути и все.
     
  8. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.236
    Адрес:
    там-сям
    Тебе @MouseZver попытался подсказать, но не очень понятно. я тоже только со второго раза понял.
    вместо test('foo') пиши test(foo::class) и тогда в параметр подставится полное имя вместе с неймспейсом!!! магия!!!
     
    AlexandrS нравится это.
  9. AlexandrS

    AlexandrS Активный пользователь

    С нами с:
    30 сен 2017
    Сообщения:
    659
    Симпатии:
    103
    Адрес:
    Краснодар
    да, я про это знал, но подставится неймспейс, а по use класс находится в другом месте и поэтому ошибка выходит.
     
  10. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.236
    Адрес:
    там-сям
    омайгад! ты любишь всё усложнять?
    --- Добавлено ---
    если неправильно использовать, то конечно будет ошибка. исправлять ошибки с помощью других ошибок не надо.
    --- Добавлено ---
    PHP:
    1. <?php
    2. namespace App\Containers\Models;
    3.  
    4. use Illuminate\Database\Eloquent\Model;
    5.  
    6. class Container extends Model
    7. { ... }
    Model "разворачивается" в \Illuminate\Database\Eloquent\Model. а не \App\Containers\Models\Model.
    такое использование тебе понятно? здесь нет ошибки.

    точно также будет разворачиваться в такой конструкции
    PHP:
    1. print('Model'); // выведет "Model"
    2.  
    3. print(Model::class); // выведет "\Illuminate\Database\Eloquent\Model"
    как можно здесь накосячить? только если забыть задать этот класс в use. тогда будет использоваться текущий неймспейс, а не тот, который надо.
     
    AlexandrS нравится это.
  11. AlexandrS

    AlexandrS Активный пользователь

    С нами с:
    30 сен 2017
    Сообщения:
    659
    Симпатии:
    103
    Адрес:
    Краснодар
    Тысячи благодарностей!
    Проблема в том что ошибка вылазила по той причине, что делалось это мной криворуко.
    Сейчас с помощью более развернутой инфы всё норм! ;):)
     
  12. AlexandrS

    AlexandrS Активный пользователь

    С нами с:
    30 сен 2017
    Сообщения:
    659
    Симпатии:
    103
    Адрес:
    Краснодар
    Но вот загвоздка. Всё это работает только в родительском классе, там где конкретно прописан USE, а если я наследуюсь и расшираю метод, то
    PHP:
    1. print(Model::class);
    выдаст -> немспейс\Model
    а если пропишу в этом файле USE то будет корректно

    И получается что если наследоваться то USE нужно постоянно тягать и выходит что дублировать.

    И выходит что этот "ОМАЙГАД"

    PHP:
    1.     private function classNames($className)
    2.     {
    3.         $classNames = [
    4.                         'Foo'=>'framework\Foo\Foo',
    5.                         'Bar'=>'framework\Bar\Bar'
    6.                       ];
    7.         return $classNames[$className];
    8.     }
    избавляет от дублирования USE в наследниках

    Либо я снова что-то недопонимаю.
     
    #12 AlexandrS, 13 дек 2019
    Последнее редактирование: 13 дек 2019