За последние 24 часа нас посетил 55631 программист и 1618 роботов. Сейчас ищут 1230 программистов ...

Относительные имена в namespace

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

  1. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    Привет всем)) подскажите или направьте где почитать..

    есть автозагрузка
    Код (Text):
    1. spl_autoload_register(function($className) {
    2.     $className = ltrim($className, '\\');
    3.     $fileName = '';
    4.     $namespace = '';
    5.     if ($lastNsPos = strrpos($className, '\\')) {
    6.         $namespace = substr($className, 0, $lastNsPos);
    7.         $className = substr($className, $lastNsPos + 1);
    8.         $fileName = DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    9.     }
    10.     $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
    11.     $fileName = __DIR__ . $fileName;
    12.     if (file_exists($fileName)) {
    13.     var_dump($fileName);
    14.         require $fileName;
    15.     }
    16. });

    есть файл в проекте /models/File.php
    Код (Text):
    1. namespace models;
    2. class File {
    3. .....
    4. }
    есть еще один файл /vendors/core/models/File.php
    Код (Text):
    1. namespace models;
    2. class File {
    3. .....
    4. }
    как правильно обращаться к второму файлу, при том что namespace у него должен быть относительный а не абсолютный..
    первый работает зашибись..
    второй инклудится в автозагрузке... но пхп не видит его как класс..
    везде где читаю - везде в общем.. а вот как такое решение сделать - не могу найти..
    может гуглю не правильно..

    Спасибо))
     
  2. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    прям вот так и есть? неймспейс - моделс и там и там, и класс - файл (ВДРУГ!) и там и там? не взлетит потому что будет фаталка по редекларации класса.
     
    Алекс8 нравится это.
  3. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    да.. прям так и есть))..
    одинаковые файлы с одинаковым относительным расположением.. но с разным абсолютным..
    смотрю на Yii2 там пространство имен по другому реализовано, не так как у меня..
    в вендорах там пространства имен отличаются от путей в проекте.. там через компосер идет автозагрузка.. и файлы явно инклудятся компосерным аутолоадом..
     
  4. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Ты не понял. Когда ты обратился к первому классу (и допустим автолод его успешно подгрузил) то в памяти появился класс с полным квалифицированным именем \models\File.
    Потом ты пытаешься обратиться к этому же классу. Он уже доступен. Ну допустим ты не умеешь автозагрузку и прописываешь руками подключение второго файла. А в нем описание класса с полным квалифицированным именем... \models\File. Того, который уже загружен в памяти...

    PHP Fatal error: Cannot declare class File, because the name is already in use in ...

    Поэтому я повторяю вопрос. У тебя точно два файла с одинаковым классом лежащим в одном нейпспейсе?
     
    Алекс8 нравится это.
  5. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    Да.. все точно так как я описал..
    два одинаковый файла, оба лежат в директориях models только один в корне, а второй в vendors/core
    когда я подключаю класс из вендорса
    use vendors\core\models\File;
    то автозагрузка его грузит require но сам пхп выдает ошибку
    Fatal error: Uncaught Error: Class 'vendors\core\models\File' not found
    потому что там неймспейс иной чем в use

    вот у меня в связи с этим вопрос.. как коректно подключать такие вот классы с относительными неймспейсами..
     
  6. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Алиасом пробовал?
     
    Алекс8 нравится это.
  7. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    да.. сразу попробовал..
    Код (Text):
    1. use vendors\core\models\File as FileTemplate;
    2.  
    3. $file = new FileTemplate;
     
  8. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Не такой алиас. Это ты написал "хочу во в этом данном файле не ломать пальцы и не копипастить vendors\core\models\File а обращаться по короткому имени - FileTemplate", а я говорю про class_alias
     
    Алекс8 нравится это.
  9. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    попробовал)) не хочет..
    Код (Text):
    1. class_alias('blank\core\models\File', 'coreFile');
    2.  
    3. $file = new coreFile;
    путь сменил для того что бы эксперементировать.. все равно получаю Warning: Class 'blank\core\models\File' not found in
    хотя сам файл с классом инклудится отлично..
    в тоже время если прописываешь в неймспейсе полный путь - все начинает работать...
     
  10. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    второй автолоадер сделай и укажи ему другой корень
     
    Алекс8 нравится это.
  11. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    а как тогда выбирать каким автолоадером грузить?
     
  12. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Порядком. У меня в нескольких проектах порно из автолоадеров:
    1. Собственно неймспейс проекта (\проект\) - в /либ/проект/
    2. Автосборка проекта (\проект\) - в /либ/билд/проект/
    3. Классы в глобальной области (* без \) - в /либ/глобал/
    4. Прототипы переопределений (\*\) - в /либ/контриб/*/
    5. Классы композитора (\*\) - в /либ/композер (их туда перекладывает сам композер из папки /вендор/)

    Запрос \Проект\Секция\Класс - отработает №1. Если не найдет класс - отработает №2. №4. №5. Далее ошибка.
    Запрос \КакойТоПСРНольКласс - отработает только №2. Иначе - ошибка.
    Запрос \Вася\Огнемёт - в №4 поищем есть ли переопределение. Иначе посмотрим в №5 и потом ошибка.
    И так далее. Короче знаю толк в извращениях. Но суть прежняя - автолоадеры исполняются в порядке встречи объявлений при выполнении скрипта.
     
    Алекс8 нравится это.
  13. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    тогда странно как то реализованы неймспейсы... хочу взять чужой класс, и что получается надо прописывать в нем свои неймспейсы..
     
  14. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Но ведь ещё есть наследование. Берешь чужой класс, расширяешь его своим, используешь свой. даже не обязательно каким-то кодом наполнять это расширение. просто майкласс экстендс вендоркласс {}
     
    Алекс8 нравится это.
  15. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.815
    Симпатии:
    1.332
    Адрес:
    Лень
  16. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    В том то и фишка что я его наследовать не могу) он мне нужен не весь а только как наследство))
     
  17. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Почему не можешь наследовать? Вендор придумал класс, разместил его в своём неймспейсе. Ты придумываешь надстройку, размещаешь в своём неймспейсе. Обращаешься к своему - автолоадер этот файл подключает, класс требует зависимость, автолоадер и этот файл подключает. Я как-то не особо вникаю в чем проблема.
     
  18. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    я не понял чем эта автозагрузка мне поможет?? вроде тоже самое только пути указаны явно для некоторых классов..

    фишка в том что автозагрузчик мой видит этот файл когда я пытаюсь создать объект даже удачно иклудит его..
    но дальше говорит что не могу найти класс...
    как только я в этом классе меняю неймспейс на полный путь.. - тогда все зашибись..

    вот я отключаю все автозагрузки и делаю вот так вот..
    Код (Text):
    1.  
    2. $file = include __DIR__ . '\blank\core\models\File.php';
    3. var_dump($file); //int 1
    4. $file = new File;
    т.е. файл инклудится но изза того что там не полный неймспейс - пхп его не видит как класс..

    если убираю из файла вообще неймспейс - то все отлично работает..
    неужели никто никогда с подобной задачей не сталкивался..
     
  19. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    Создавай объект включительно с наймспйсе в имени класса, может поможет.
    Или use до объявления класса, где используешь тот класс.
    Если я все правильно понял, должно помочь.
     
    Алекс8 нравится это.
  20. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Ты их в одном выполнении скрипта пытаешься дёрнуть?
     
    Алекс8 нравится это.
  21. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    пытался так сразу сделать..
    тоже самое..

    и так
    Код (Text):
    1.  
    2. $file = new blank\core\models\File;
    и так
    Код (Text):
    1.  
    2. use blank\core\models\File;
    3. $file = new File;
    файл весело инклудится - а потом пхп говорит что все плохо..
    --- Добавлено ---
    Вот смоделировал ситуацию)) кому интересно скачайте посмотрите)
    --- Добавлено ---
    хоть одновременно хоть не одновременно все равно не получается..
    выше пример дал..
    мне вообще идеально было бы наследоваться от того который в вендорсах..
     

    Вложения:

    • test.zip
      Размер файла:
      1,3 КБ
      Просмотров:
      1
    #21 Алекс8, 14 дек 2017
    Последнее редактирование: 14 дек 2017
  22. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    Ты тут противоречия не видишь?
     
    Алекс8 нравится это.
  23. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    use указывает какой неймспейс нам использовать... в файле /vendors/core/models/File.php он указан от корня /vendors/core/
    а я указываю в use полный путь. .я понимаю что это вроде не правильно. . но в документации что то писали про относительные пути, я тешу себя надеждой что они все таки должны работать)
     
  24. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    @Алекс8, в самом PHP namespace никак не связан с путями к файлу, и может быть по любому пути любой. Это уже изобретение программистов - привязать неймспесы к путям, интерпретатор про это нихрена не знает. Поэтому во всех файлах должен быть полный namespace
     
    Алекс8 нравится это.
  25. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    то есть в данном конкретном примере если у двух файлов одинаковые неймспейсы я никак не могу обеими классами воспользоваться??
    печалька.. .