Фатальная ошибка при расширении класса, у которого нет пространства имен

#php #namespaces

Вопрос:

У меня два занятия, Database и States . Классу Database не назначено пространство имен. Класс States , записанный в файле states.php, имеет пространство имен, назначенное, как показано ниже:

 namespace Resources;      
require_once 'database.php';
  
$states = new States();
echo $states->readAll();

class States extends Database{
    private $db;
  
    public function __construct(){
      $this->db = new Database();
    }
  
    function readAll(){
      return $this->db->Execute('SELECT * FROM states;');
    }      
}
 

Если я введу URLадрес http://localhost/mydomain/objects/states.php который должен создать экземпляр класса и показать список состояний, возникает ошибка в виде:

Фатальная ошибка: Неперехваченная ошибка: Класс «РесурсыБаза данных» не найден в C:xampphtdocsmydomainobjectsstates.php на линии 5

Если я удалю строку namespace Resources; , код запустится.

Недавно я решил внедрить пространства имен на своем веб-сайте, поэтому, скорее всего, я делаю что-то не так.

Какая-нибудь помощь, пожалуйста?

Ответ №1:

В руководстве по PHP есть раздел, посвященный пространствам имен, который стоит прочитать. В частности, взгляните на эту страницу, проводя аналогию с файловой системой:

Тот же принцип может быть применен к элементам пространства имен в PHP. Например, на имя класса можно ссылаться тремя способами:

  1. Неполное имя или незафиксированное имя класса, например $a = new foo(); или foo::staticmethod(); . Если текущее пространство имен является currentnamespace , это решает currentnamespacefoo . Если код является глобальным, не содержащим пространства имен, это решает foo проблему .
  2. Полное имя или имя класса с префиксом, например $a = new subnamespacefoo(); или subnamespacefoo::staticmethod(); . Если текущее пространство имен является currentnamespace , это решает currentnamespacesubnamespacefoo . Если код является глобальным, не содержащим пространства имен, это решает subnamespacefoo проблему .
  3. Полное имя или имя с префиксом с глобальным оператором префикса, таким как $a = new currentnamespacefoo(); или currentnamespacefoo::staticmethod(); . Это всегда приводит к буквальному имени, указанному в коде, currentnamespacefoo .

В вашем примере Database это «неполное имя», поэтому применяется пункт 1. Текущее пространство имен есть Resources , поэтому оно ссылается на ResourcesDatabase . Если вы удалите namespace Resources; строку, код станет «глобальным кодом без пространства имен», поэтому он относится к just Database .

Для ссылки на класс Database в текущем пространстве Resources имен можно использовать «полное имя», как описано в пункте 3. Так что в данном случае вы бы написали class States extends Database .

Есть и другие способы его написания, такие как добавление use операторов для импорта/псевдонима имени, но мне нет смысла копировать здесь все руководство по PHP.

Комментарии:

1. Спасибо. Только добавление раньше Database выполнило эту работу.