Namespace und use...ich dreh noch mal durch

bofh1337

Erfahrenes Mitglied
Moin :)
Da ich mir bis jetzt die PHP-Klamotte zum Hobby gemacht und selber beigebracht habe, es also nicht Jobmässig damit zu tun habe, stehe ich nun vor einem kleinen Problem:

Ich habe bei mit "PHP 5.4.13-2~precise+1" am laufen, aber irgendwie scheint weder "namespace" noch "use" für OOP bei mir zu laufen:

Die /index.php:
PHP:
<?php

use compress\compressor;

include 'loader.php';

$params = array (
    'compressor' => 'zip',
    'owndir' => true
);

$something = '';

$t = new compressor ();
$t->load ('Archiv');
$t->extract ($params, $something);

?>

Die /loader.php (08/15 loader, erfüllt aber seinen zweck, inkl. debug-infos):
PHP:
<?php

function __autoload ($class_name)
{
    static $list;

    $class =  str_replace ('\\', DIRECTORY_SEPARATOR, $class_name) . '.php';

    include_once './' . $class;

    if (!$list)
    {
        $list = array ();
    }
    if (!in_array ($class, $list))
    {
        $list[] = $class;
    }
    echo '<pre>';
    var_dump ($list);
    echo '</pre>';
}

?>

Die /compress/compressor.php:
PHP:
<?php

namespace compress\compressor;

use compress\driver\tar,
    compress\driver\Zip;

class compressor
{
    const FILE_ZIP = 0;
    const FILE_RAR = 1;
    const FILE_TAR_GZ = 2;
    //...
    protected $driver;
    protected $file;

    public function __construct ()
    {
        ;
    }

    public function __destruct ()
    {
        if (!empty ($this->driver))
        {
            unset ($this->driver);
        }
    }

    public function load ($file, $driver = self::FILE_ZIP)
    {
        $this->driver = new Zip ();
    }

    public function extract ($params, $something)
    {
        $this->driver->extract ($params, $something);
    }

    public function compress ($params, $something)
    {
        $this->driver->extract ($params, $something);
    }
}

?>

Von der loader.php bekomme ich die Infos, das die "/compress/compressor.php" geladen wurde...aber vom xdebug nur die Meldung:
Fatal error: Class 'compress\compressor' not found in /var/www/httpdocs/namespace/index.php on line 14

Kann mir jemand verraten, wo da der Fehler liegt? Ich kann das ganze Paket auch mal als Zip hoch laden ;)
 
Also dein Problem wird sein, dass du in compressor.php folgendes notiert hast:

PHP:
<?php

namespace compress\compressor;

use compress\driver\tar,
    compress\driver\Zip;

class compressor

Damit ist der absolute Pfad zur Klasse compress\compressor\compressor. Also doppelt-gemoppelt. Versuch es mal so:

PHP:
namespace compress;

use compress\driver\tar,
    compress\driver\Zip;

class compressor

Man kann es sich recht einfach merken: Der Namespace muss dem Pfad im Dateissystem entsprechen.

EDIT: genauer: Der Namespace muss dem Ordner-Pfad im Dateissystem entsprechen.
 
Zuletzt bearbeitet:
Mh, ich seh so direkt keinen Fehler. Hast du mal probiert, die datei direkt ohne autoload zu includen?
 
Da er autoloading verwendet und den Namespace auf seine Ordner-Struktur abbildet, schon.

Probiers doch einfach aus ;-) Mit "namespace compress\compressor" und der Klasse "compressor" funktioniert "use compress\compressor" nicht, wenn er "namespace compress" notiert und die Klasse "compressor" nennt, funktioniert das "use compress\compressor".

Oder anders um es etwas zu verdeutlichen:

compress/Compressor.php
PHP:
namespace compress;

class Compressor
{
 ....
}

index.php
PHP:
use compress\Compressor;

$compressorObject = new Compressor();
.....

Der voll-qualifizierte Bezeichner für Compressor wäre damit "compress\Compressor", also (physikalisch) bestehend aus Ordner "compress" und Datei "Compressor.php". Natürlich ist das erstmal auf seinen Anwendungsfall zugeschnitten. Das er sich nicht an das Konzept der Namensraum-Konvetionen hält, ist kein Grund, warum es nicht funktionieren sollte :-)
 
Ja, schon klar, ich dachte nur deine Aussage wäre generell, das ist aber falsch. Man kann auch ein namespace-System schaffen das völlig unabhängig von dem Filesystem ist - auch wenn das sehr wahrscheinlich nicht sinnvoll ist und im Chaos endet :D
 
Nein, wenn es den Eindruck erweckt hat: Das mit dem "einfach zu merken" bezieht sich nur auf das System, wie bofh1337 es sich zusammen gezimmert hat, weil ich den Eindruck habe, das er das System selbst noch nicht verstanden hat.
 
Wow, Saftmeister hatte echt recht gehabt, ich habe das "compress/compressor" in "compress" geändert und schon bin ich 4 Schritte weiter :)

Debug-Ausgabe in der loader.php ist nun:
PHP:
array (size=3)
  0 => string 'compress/compressor.php' (length=23)
  1 => string 'compress/interfaces/driverinterface.php' (length=39)
  2 => string 'compress/driver/base.php' (length=24)

Demnach werden da schon einige Classen mehr angesprochen, als ich angenommen habe :)

Selbst die Ausgabe vom xdebug ist mehr als super...auch wenn sie noch ein paar Fehler wie das doppelte Backslash enthalten :)

Code:
Call Stack
#	Time	Memory	Function	Location
1	0.0003	233176	{main}( )	../test.php:0
2	0.0015	248376	compress\compressor->load( $file = 'Archiv', $driver = ****? )	../test.php:15
3	0.0015	248672	__autoload( $class_name = 'compress\\driver\\Zip' )	../test.php:32
4	0.0019	253256	include_once( '/var/www/httpdocs/namespace/compress/driver/zip.php' )	../loader.php:23

So kleine Ursache, aber so große Wirkungen...danke euch erst mal :)
 
Selbst die Ausgabe vom xdebug ist mehr als super...auch wenn sie noch ein paar Fehler wie das doppelte Backslash enthalten :)

Code:
Call Stack
#	Time	Memory	Function	Location
1	0.0003	233176	{main}( )	../test.php:0
2	0.0015	248376	compress\compressor->load( $file = 'Archiv', $driver = ****? )	../test.php:15
3	0.0015	248672	__autoload( $class_name = 'compress\\driver\\Zip' )	../test.php:32
4	0.0019	253256	include_once( '/var/www/httpdocs/namespace/compress/driver/zip.php' )	../loader.php:23

Das ist kein Fehler. Das ist so gewollt. Damit soll angezeigt werden, das es sich tatsächlich um Backslashes handelt und nicht etwa um maskierte Zeichen. \d steht nämlich z.B. für eine bestimmte Zeichen-Klasse bei regulären Ausdrücken.
 
Achso, ok...ich hätte jetzt auf einen Fehler getippt...naja, Namespace ist eben noch etwas Neuland für mich, aber wohl der richtige Weg, wenn man sich weiterhin damit beschäftigen will :)

Danke dir :)
 
Zurück