За последние 24 часа нас посетили 54469 программистов и 1779 роботов. Сейчас ищут 925 программистов ...

Почему php не выдает ошибку переопределения класса

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

Метки:
  1. yurri_87

    yurri_87 Новичок

    С нами с:
    29 авг 2017
    Сообщения:
    37
    Симпатии:
    5
    есть 2 файла в корне сайта:
    global.php:
    Код (Text):
    1. <?php
    2. // global.php
    3. class Lister{
    4.     public static function helloWorld()    {
    5.         print "Привет из глобального пространства";
    6.     }
    7. }
    и index.php:
    Код (Text):
    1. <?php
    2. // index.php
    3. namespace com\getinstance\util;
    4. require_once 'global.php';
    5.  
    6. class Lister{
    7.     public static function helloWorld(){
    8.         print "Привет из " . __NAMESPACE__ . "<br>";
    9.     }
    10. }
    11.  
    12. Lister::helloWorld();
    13. \Lister::helloWorld();
    мне непонятно, почему при определении класса Lister в файле index.php (на 6 строке) PHP не выдает ошибку, ведь используй я вместо require оператор use, подключающий пространство имен с таким же классом Lister, PHP выдал бы ошибку.
    Я новичек, поэтому прошу объяснить на пальцах.
     
  2. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.818
    Симпатии:
    1.333
    Адрес:
    Лень
    потому что они в двух разных космических пространствах.
    Зацени фильм https://zona.mobi/movies/interstellar
    поймешь
    --- Добавлено ---
    PHP:
    1. Lister::helloWorld(); # берет пространство файла в итоге com\getinstance\util\Lister::helloWorld()
    2. \Lister::helloWorld(); # \ перед именем, означает вызывать что - то с нашего человекоподобного пространства :)
     
    yurri_87 нравится это.
  3. виталий032

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

    С нами с:
    31 янв 2014
    Сообщения:
    227
    Симпатии:
    30
    Адрес:
    Владивосток
    Use не подгружает файлы, а просто указывает использование пространства имен. Соответственно, файл не был бы подключен, глобальное пространство было бы не определено, вот он и выдал бы ошибку, что не может найти глобальное пространство. Но можно, конечно, писать namespace-ы как пути, а потом настроить composer на загрузку файлов при использовании use, что и используется во фреймворках.
     
    yurri_87 нравится это.
  4. yurri_87

    yurri_87 Новичок

    С нами с:
    29 авг 2017
    Сообщения:
    37
    Симпатии:
    5
    я имел ввиду использование конкретного класса:
    Код (Text):
    1. use anothernamespace\Lister;
     
  5. yurri_87

    yurri_87 Новичок

    С нами с:
    29 авг 2017
    Сообщения:
    37
    Симпатии:
    5
    незнаю, меня тут не наругают сильно за оффтоп.. но
    Gravity.php:
    PHP:
    1. <?php
    2. //Gravity.php
    3. interface Gravity{
    4.     static function sendQueantumData();
    5. }
    BlackHole.php:
    PHP:
    1. <?php
    2. // BlackHole.php
    3. namespace BlackHole;
    4. require_once 'Gravity.php';
    5. require_once 'Earth.php';
    6. use Gravity;
    7. use Earth\Room;
    8.  
    9. class QuantumData{
    10.     public static $quantumData = '1+1 != 2';
    11. }
    12.  
    13. class DataTransmitter implements Gravity{
    14.     private static $veryImportantQuantumData = '';
    15.     public static function getQuantumData(){
    16.         self::$veryImportantQuantumData = QuantumData::$quantumData;
    17.     }
    18.  
    19.     public static function sendQueantumData(){
    20.         self::getQuantumData();
    21.         Room::$watch_data .= self::$veryImportantQuantumData;
    22.     }
    23. }
    24.  
    25. DataTransmitter::sendQueantumData();
    26. echo Room::$watch_data;
    Earth.php:
    PHP:
    1. <?php
    2. // Earth.php
    3. namespace Earth;
    4. require_once 'Gravity.php';
    5. use Gravity;
    6. class Room implements Gravity{
    7.     static $watch_data = '';
    8.     static function sendQueantumData(){
    9.         echo $watch_data;
    10.     }
    11.  
    12.     static function STAY(){
    13.        return "<img src='https://admin.mashable.com/wp-content/uploads/2013/07/crying-waterfalls.gif'>";
    14.     }
    15. }
     
    #5 yurri_87, 17 окт 2017
    Последнее редактирование: 17 окт 2017
  6. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.818
    Симпатии:
    1.333
    Адрес:
    Лень
    @yurri_87

    ну? вижу с пространствами справился:)
     
  7. yurri_87

    yurri_87 Новичок

    С нами с:
    29 авг 2017
    Сообщения:
    37
    Симпатии:
    5
    про пространства я понимал и раньше.
    просто мне не совсем понятно, почему при подключении (require_once global.php) не происходит попытка определения класса Lister. Ведь по сути код файла global.php просто вставляется и выполняется. Так?
    и мы начинаем использовать пространство имен namespace com\getinstance\util, а потом уже в нем подключаем файл global.php. Не совсем ясно кака это работает. Аналогия с фильмом превосходная, однако нюансы не раскрывает. Если можно чуточку подробнее.
    аналогию бы, раскрывающую как работает USE.
    Лайкну в любом случае, конечно.
    Фильм шедевр, редко так снимают, плакал как мелкий, при каждом пересмотре после фразы "потому что мой папа пообещал мне..." С тех пор посматриваю почаще в сторону фантастики, вдруг что-то похожее сняли.
     
    #7 yurri_87, 18 окт 2017
    Последнее редактирование: 18 окт 2017
  8. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.818
    Симпатии:
    1.333
    Адрес:
    Лень
    потому что выше как там его... index.php находится в пространстве com\getinstance\util и подключает global.php у которого пространство дефолт.
    \Lister::helloWorld();
    обратились к дефолтному астралу где находится класс Листер
    конечно есть, лови :)
    https://zona.mobi/movies/peklo-2007
     
    yurri_87 нравится это.
  9. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Это двойственность php. По сути, require просто включает файл, да. Но, при этом, у него остаётся свой namespace, а не пространство имён определённое в том файле, в котором он включается. Иначе бы от пространств имён толку не было. В пыхе много таких штук, его за это часто ругают.
     
    yurri_87 нравится это.
  10. yurri_87

    yurri_87 Новичок

    С нами с:
    29 авг 2017
    Сообщения:
    37
    Симпатии:
    5
    Для ясности картины мне осталось понять смысл "use". Смысл только в том, чтобы создать алиас на случай совпадения имен классов и в том чтобы укоротить пути?

    Ведь по сути можно использовать только require и все.

    А "use as" используется только когда реквайрится файл с таким же неймспейсом и таким же именем класса?
     
  11. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    use - чтоб не писать каждый раз полное имя, да. use as - чтоб нивелировать конфликт имён с текущим пространством.
    --- Добавлено ---
    Ещё про автозагрузку и PSR прочитайте, для того, чтоб уже совсем разобраться с этим. Позволяют убрать необходимость require
     
    yurri_87 нравится это.