Otrzymuję ten błąd, gdy próbuję użyć automatycznego ładowania i przestrzeni nazw:
Błąd krytyczny: nie znaleziono klasy „Class1” w /usr/local/www/apache22/data/public/php5.3/test.php w linii 10
Czy ktoś może mi powiedzieć, co robię źle?
Oto mój kod:
Class1.php:
<?php
namespace Person\Barnes\David
{
class Class1
{
public function __construct()
{
echo __CLASS__;
}
}
}
?>
test.php:
<?php
function __autoload($class)
{
require $class . '.php';
}
use Person\Barnes\David;
$class = new Class1();
?>
AS
. Nie dlatego to rozwiązanie działa. Możesz równie łatwo zrobić:use Person\Barnes\David\Class1;
(co jest równoważneuse Person\Barnes\David\Class1 as Class1;
).use Person\Barnes\David\Class1;
, aby to zrobić$class = new Class1();
. Zuse Person\Barnes\David;
musisz zrobić$class = new David\Class1();
. Słowouse
kluczowe samo w sobie jest odpowiednikiemuse Person\Barnes\David\Class1 as Class1;
lubuse Person\Barnes\David as David;
, odpowiednio dla każdego przykładu.Jak wspomniano Pascal MARTIN, należy zamienić „\” na DIRECTORY_SEPARATOR, na przykład:
Sugerowałbym również przeorganizowanie struktury katalogu, aby kod był bardziej czytelny. To może być alternatywa:
Struktura katalogów:
Plik:
/ProjectRoot/lib/Person/Barnes/David/Class1.php
Plik:
/ProjectRoot/test.php
źródło
Twoja
__autoload
funkcja otrzyma pełną nazwę klasy, w tym nazwę przestrzeni nazw.Oznacza to, że w Twoim przypadku
__autoload
funkcja otrzyma „Person\Barnes\David\Class1
”, a nie tylko „Class1
”.Więc musisz zmodyfikować swój kod do automatycznego ładowania, aby poradzić sobie z tego rodzaju „bardziej skomplikowaną” nazwą; często używanym rozwiązaniem jest organizowanie plików przy użyciu jednego poziomu katalogu na „poziom” przestrzeni nazw i podczas automatycznego ładowania zastąp „
\
” w nazwie przestrzeni nazw znakiemDIRECTORY_SEPARATOR
.źródło
__autoload
funkcja otrzyma pełną nazwę klasy, w tym nazwę przestrzeni nazw” - jest to prawdą tylko wtedy, gdy masz jawnieuse
daną klasę, do której próbujesz się odwołać, a nie, jeśli po prostuuse
dałeś przestrzeń nazw, do której należy. Błąd OP polegał na tym, żeuse
utworzył przestrzeń nazw zawierającą klasę, a następnie spodziewał się, że jego funkcja automatycznego ładowania w magiczny sposób przejdzie przez pełną ścieżkę klas. Ta odpowiedź tak naprawdę nie odnosi się do błędu PO.Robię coś takiego: Zobacz ten przykład GitHub
źródło
Znalazłem ten klejnot od Flysystem
źródło
Widzę, że funkcje automatycznego ładowania otrzymują „pełną” nazwę klasy - ze wszystkimi przestrzeniami nazw ją poprzedzającymi - w dwóch następujących przypadkach:
Widzę, że funkcje automatycznego ładowania NIE otrzymują pełnej nazwy klasy w następującym przypadku:
AKTUALIZACJA: [c] jest błędem, a zresztą tak nie jest, jak działają przestrzenie nazw. Mogę zgłosić, że zamiast [c], następujące dwa przypadki również działają dobrze:
Mam nadzieję że to pomoże.
źródło
use
słowo kluczowe nie działa poprawnie w interaktywnym interfejsie wiersza poleceń PHP (php --interactive
);Używam tego prostego hacka w jednej linii:
źródło
miał ten sam problem i właśnie znalazłem to:
Kiedy tworzysz strukturę podfolderu pasującą do przestrzeni nazw klas zawierających ją, nigdy nie będziesz musiał nawet definiować autoloadera.
Zadziałało jak urok
Więcej informacji tutaj: http://www.php.net/manual/en/function.spl-autoload-register.php#92514
EDYCJA: powoduje to problem w Linuksie z powodu odwrotnego ukośnika ... Zobacz tutaj działające rozwiązanie immeëmosol
Namespace Autoload działa w systemie Windows, ale nie w systemie Linux
źródło
Używanie ma problem, chociaż jest to zdecydowanie najszybsza metoda, oczekuje również, że wszystkie nazwy plików będą pisane małymi literami.
Na przykład:
Plik zawierający klasę SomeSuperClass musiałby nazywać się somesuperclass.php, jest to problem w przypadku korzystania z systemu plików z rozróżnianiem wielkości liter, takiego jak Linux, jeśli plik nosi nazwę SomeSuperClass.php, ale nie jest to problem w systemie Windows.
Używanie __autoload w kodzie może nadal działać z aktualnymi wersjami PHP, ale spodziewaj się, że ta funkcja zostanie wycofana i ostatecznie usunięta w przyszłości.
Więc jakie opcje zostały:
Ta wersja będzie działać z PHP 5.3 i nowszymi wersjami i pozwala na używanie nazw plików SomeSuperClass.php i somesuperclass.php. Jeśli używasz wersji 5.3.2 i nowszych, ten autoloader będzie działał jeszcze szybciej.
źródło
str_replace ([ '_','\\'] '/', $className );
jest dwa razy szybsze niż dwa str_replaceNiedawno uznałam, że odpowiedź Tanerkuca jest bardzo pomocna! Chciałem tylko dodać, że użycie
strrpos()
+substr()
jest nieco szybsze niżexplode()
+end()
:źródło
Dorzucę moje dwa centy dla względnie początkujących lub czegokolwiek, kto chce prostej konfiguracji spl_autoload_register () bez całej teorii: po prostu utwórz jeden plik php dla każdej klasy, nazwij ten plik php tak samo jak nazwa Twojej klasy i zachowaj pliki swoich klas w tym samym katalogu co dany plik php, to zadziała:
Wyszukiwanie elementów w tej funkcji powinno odpowiedzieć na pytanie, jak to działa. PS: Używam Linuksa, a to działa na Linuksie. Użytkownicy systemu Windows powinni najpierw to przetestować.
źródło
https://thomashunter.name/blog/simple-php-namespace-friendly-autoloader-class/
Będziesz chciał umieścić swoje pliki klas w folderze o nazwie
Classes
, który znajduje się w tym samym katalogu, co punkt wejścia do aplikacji PHP. Jeśli klasy używają przestrzeni nazw, przestrzenie nazw zostaną przekonwertowane na strukturę katalogów.W przeciwieństwie do wielu innych programów ładujących, podkreślenia nie będą konwertowane na struktury katalogów (trudno jest zrobić pseudo-przestrzenie nazw PHP <5.3 razem z rzeczywistymi przestrzeniami nazw PHP> = 5.3).
Będziesz chciał umieścić następujący kod w swoim głównym skrypcie PHP (punkcie wejścia):
Oto przykładowy układ katalogu:
źródło
źródło