BRAINSTORMING PHP/SQL/HTML/JS/CSS Ihr habt eine Idee, aber keinen genauen Ansatz? Diskutiert mit anderen Usern des Forums über eure Gedankengänge um evtl. hilfreiche Ideen zu bekommen!
Normale Fragen bitte weiterhin in die entsprechenden Foren! |
 |
|

08-05-2008, 22:17
|
|
Griecherus
PHP Senior
|
|
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
|
|
Namespaces und Autoloading
Ich experimentiere gerade mit PHP6 und bin an den Namespaces hängen gelieben, jedenfalls im Zusammenhang mit __autoload. Bisher habe ich das Laden (am Beispiel einer Bibliothek) gelöst, in dem ich alle Dateien mit den zugehörigen Pfaden aus dem Bibliotheksverzeichnis ausgelesen und gespeichert habe, da meine Klassenname - anders als Zend Framework und Co. - kein Abbild ihres Dateipfads darstellen.
PHP-Code:
public static function load_library()
{
$loaded_library = array();
foreach (new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(dirname(__FILE__))) as $file)
{
if (substr(strrchr($file->getFilename(), '.'), 1) == 'php')
{
$filepath = $file->getPathname();
require_once $filepath;
$loaded_library[end(get_declared_classes())] = $filepath;
}
}
return $loaded_library;
}
PHP-Code:
public static function __autoload($class_name)
{
$library = self::load_library();
if (isset($library[$class_name]))
{
require_once $library[$class_name];
return true;
}
return false;
}
Namespaces scheinen mir auf den ersten Blick allerdings eine nette Lösung zu bieten, die die ganze Sache simplifiziert. Eine entsprechende Verzeichnisstruktur vorausgesetzt, ließe sich von den Namespaces auf die Dateipfade der Klassen schließen.
Aus Http::Request würde nach einem simplen str_replace und strtolower http/request.php. Allerdings habe ich in dieser Richtung schon von Problematiken gelesen. Hat jemand von euch diesbezüglich schon Erfahrungen gemacht oder handhabt das auf eine ähnliche Weise?
Grüße
Geändert von Griecherus (09-05-2008 um 00:24 Uhr)
|

09-05-2008, 02:43
|
|
PHP-Desaster
PHP Expert
|
|
Registriert seit: Mar 2006
Beiträge: 3.104
|
|
Ich habe gerade auch mal ein wenig rumgespielt. Verwendest du __autoload mit einer Klasse aus einem Namensraum, so wird der vollqualifizierte Name der Funktion übergeben. Du könntest dies also auf Verzeichnisse abbilden. Selbst nach einer use-Direktive wird der Name korrekt aufgelöst, scheint also eine sichere Möglichkeit zu sein.
|

09-05-2008, 12:32
|
|
Griecherus
PHP Senior
|
|
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
|
|
Ja, das ist das Gute daran. __autoload kann mit einem simplen
PHP-Code:
str_replace('::', DIRECTORY_SEPARATOR, $class_name);
den Namensraum in eine Verzeichnissstruktur abbilden. Allerdings hat sich in meinem Fall ein kleines "Hindernis" im Zusammenhang mit der Namenskonvention meiner Dateien und Klassen ergeben.
Aus class ClassName wird class_name.php. Das heisst ich müsste eine Funktion einbeziehen, die den Pascal Case Namen der Klassen in das Snake Case Format der Dateien umwandelt. Oder ich bleibe eben dabei, die Verzeichnisse auf "die alte Tour" zu durchsuchen und ein Array aus Klassen und Verzeichnissen zu bilden. Da bin ich mir noch nicht einig.
Grüße
|

09-05-2008, 22:46
|
|
PHP-Desaster
PHP Expert
|
|
Registriert seit: Mar 2006
Beiträge: 3.104
|
|
Zitat:
|
Aus class ClassName wird class_name.php. Das heisst ich müsste eine Funktion einbeziehen, die den Pascal Case Namen der Klassen in das Snake Case Format der Dateien umwandelt.
|
Das ist ja in Ordnung. Wenn du keinen Nerv hast, das selbst zu malen, portiere den Sourcecode von prototypes String.underscore auf PHP. Allerdings wird aus dem str_replace dann wohl eher ein explode und implode...
|

10-05-2008, 02:18
|
|
Griecherus
PHP Senior
|
|
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
|
|
Zitat:
Original geschrieben von PHP-Desaster
Das ist ja in Ordnung. Wenn du keinen Nerv hast, das selbst zu malen, portiere den Sourcecode von prototypes String.underscore auf PHP. Allerdings wird aus dem str_replace dann wohl eher ein explode und implode...
|
Danke für den Tipp. Ich werde mir das mal genauer ansehen. Bisher habe ich das in einer Schleife mit den String-Funktionen, also ohne Regex, gelöst:
PHP-Code:
$class_file = '';
for ($i = 0, $len = strlen($class_name); $i < $len; $i++)
{
$char = substr($class_name, $i, 1);
if (strtoupper($char) === $char)
{
$class_file .= (($class_file != '') ? '_' : '') . strtolower($char);
}
else
{
$class_file .= $char;
}
}
Grüße
|

10-05-2008, 02:19
|
|
Griecherus
PHP Senior
|
|
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
|
|
Zitat:
Original geschrieben von PHP-Desaster
Das ist ja in Ordnung. Wenn du keinen Nerv hast, das selbst zu malen, portiere den Sourcecode von prototypes String.underscore auf PHP. Allerdings wird aus dem str_replace dann wohl eher ein explode und implode...
|
Danke für den Tipp. Ich werde mir das mal genauer ansehen. Bisher habe ich das in einer Schleife mit den String-Funktionen, also ohne Regex, gelöst:
PHP-Code:
$class_file = '';
for ($i = 0, $len = strlen($class_name); $i < $len; $i++)
{
$char = substr($class_name, $i, 1);
if (strtoupper($char) === $char)
{
$class_file .= (($class_file != '') ? '_' : '') . strtolower($char);
}
else
{
$class_file .= $char;
}
}
Grüße
|

10-05-2008, 23:55
|
|
3DMax
PHP Senior
|
|
Registriert seit: Jan 2004
Beiträge: 1.916
|
|
find' ich eine gute idee, fürs autoloading namespaces (gibt es ja schon ab php 5.3.0) zu benutzen. scheint auch keine probleme zu geben:
http://php.net/manual/de/language.oo...load.php#82087
Griecherus, wenn du deine load_library() benutzt, brauchst du allerdings keine autoloading mehr, die includiert ja einfach alle php-dateien.
|

11-05-2008, 00:00
|
|
PHP-Desaster
PHP Expert
|
|
Registriert seit: Mar 2006
Beiträge: 3.104
|
|
Das gleiche steht im zweiten Post
|

11-05-2008, 00:41
|
|
Griecherus
PHP Senior
|
|
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
|
|
Zitat:
Original geschrieben von 3DMax
find' ich eine gute idee, fürs autoloading namespaces (gibt es ja schon ab php 5.3.0) zu benutzen. scheint auch keine probleme zu geben:
http://php.net/manual/de/language.oo...load.php#82087
Griecherus, wenn du deine load_library() benutzt, brauchst du allerdings keine autoloading mehr, die includiert ja einfach alle php-dateien.
|
Die wird aber nicht automatisch aufgerufen, sobald ich eine Instanz einer Klasse erstelle.
Im Übrigen ergibt sich ein unschönes Problem bei meiner load_library() Methode: Sie berücksichtigt keine Interfaces. Ich müsste sie also dahingehend erweitern, heraus zu finden, ob die jeweilige Datei eine Klasse oder ein Interface enthält und dementsprechend das library Array erstellen.
Grüße
|

11-05-2008, 01:33
|
|
PHP-Desaster
PHP Expert
|
|
Registriert seit: Mar 2006
Beiträge: 3.104
|
|
OffTopic: Meine Interfaces beginnen immer mit einem I, zum Beispiel ISortable. Vielleicht kannst du ja sowas in die Richtung verwenden 
|

11-05-2008, 01:52
|
|
Griecherus
PHP Senior
|
|
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
|
|
Zitat:
Original geschrieben von PHP-Desaster
OffTopic: Meine Interfaces beginnen immer mit einem I, zum Beispiel ISortable. Vielleicht kannst du ja sowas in die Richtung verwenden 
|
Das ist bei mir auch der Fall. Interfaces bilden die einzige Ausnahme, die (das von mir verhasste  ) Camel Case zur ihrer Benennung verwenden.
PHP-Code:
interface iInterfaceName
{
// ...
}
Allerdings dachte ich bisher eher daran, Reflections zu verwenden (resp. ReclectionClass::isInterface()).
Grüße
Geändert von Griecherus (11-05-2008 um 01:57 Uhr)
|

17-05-2008, 20:55
|
|
tontechniker
PHP Senior
|
|
Registriert seit: Jul 2005
Beiträge: 1.972
|
|
Zitat:
|
Danke für den Tipp. Ich werde mir das mal genauer ansehen. Bisher habe ich das in einer Schleife mit den String-Funktionen, also ohne Regex, gelöst:
|
Eine noch etwas schnellere Implementation:
PHP-Code:
/**
* Reverse camelizing a string
*
* @param string $string string to uncamlize
* @return string
**/
function uncamelize ( $string ) {
$string = trim ( $string );
$string = strtr ( mb_strtolower ( mb_substr ( $string, 0, 1 ) ) . mb_substr ( $string, 1 ),
array ( 'A' => '_a', 'B' => '_b', 'C' => '_c', 'D' => '_d', 'E' => '_e', 'F' => '_f', 'G' => '_g',
'H' => '_h', 'I' => '_l', 'J' => '_l', 'K' => '_k', 'L' => '_l', 'M' => '_m', 'N' => '_n',
'O' => '_o', 'P' => '_p', 'Q' => '_q', 'R' => '_r', 'S' => '_s', 'T' => '_t', 'U' => '_u',
'V' => '_v', 'W' => '_w', 'X' => '_x', 'Y' => '_y', 'Z' => '_z' ) );
return $string;
}
Zitat:
|
Allerdings dachte ich bisher eher daran, Reflections zu verwenden (resp. ReclectionClass::isInterface()).
|
Ist in der Praxis imho etwas viel Overhead fürs laden von Dateien.
Geändert von tontechniker (17-05-2008 um 20:59 Uhr)
|

18-05-2008, 00:05
|
|
Griecherus
PHP Senior
|
|
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
|
|
Danke für deinen Vorschlag. So simpel habe ich gar nicht gedacht
Zitat:
Original geschrieben von tontechniker
Ist in der Praxis imho etwas viel Overhead fürs laden von Dateien. [/B]
|
Was würdest du alternativ vorschlagen?
Grüße
|

18-05-2008, 00:19
|
|
tontechniker
PHP Senior
|
|
Registriert seit: Jul 2005
Beiträge: 1.972
|
|
Zitat:
|
Was würdest du alternativ vorschlagen?
|
Wenn du tatsächlich konsequent das "i" und CamelCase benutzt würde ich darauf prüfen. Ich lege Interfaces entweder in der normalen Ordnerstruktur ab (aus _ wird /, Beispiel Zend Framework) oder lege sie zusammen mit Klassen ab soweit sinnvoll (Beispiel: in der Datei Controller.php befindet sich mit der Klasse Controller auch noch das Interface ControllerCallInterface, das Controller implementieren die nicht auf Methoden reagieren, sondern über __call auf beliebige Werte. Wenn ein Controller aufgerufen wird und Controller.php noch nicht inkludiert, wird auf Grund der Abstammung des Controllers von der der Klasse Controller die Datei inkludiert und damit auch das Interface). Natürlich ist das beliebig handhabbar, es gibt Leute die meinen, dass man eine Datei pro Klasse / Interface bräuchte, ich finde allerdings, dass es mit der Größe des Projekts irgendwann sehr komplex und unübersichtlich wird wenn man alles aufspaltet, außerdem braucht jeder include zusätzliche Zeit - wenn man für den Controller jedesmal fünf Dateien inkludieren muss (und das auf jeder einzelnen Seite) ist das imho etwas viel.
|

26-05-2008, 17:38
|
|
Griecherus
PHP Senior
|
|
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
|
|
Zitat:
Original geschrieben von tontechniker
Eine noch etwas schnellere Implementation:
PHP-Code:
/**
* Reverse camelizing a string
*
* @param string $string string to uncamlize
* @return string
**/
function uncamelize ( $string ) {
$string = trim ( $string );
$string = strtr ( mb_strtolower ( mb_substr ( $string, 0, 1 ) ) . mb_substr ( $string, 1 ),
array ( 'A' => '_a', 'B' => '_b', 'C' => '_c', 'D' => '_d', 'E' => '_e', 'F' => '_f', 'G' => '_g',
'H' => '_h', 'I' => '_l', 'J' => '_l', 'K' => '_k', 'L' => '_l', 'M' => '_m', 'N' => '_n',
'O' => '_o', 'P' => '_p', 'Q' => '_q', 'R' => '_r', 'S' => '_s', 'T' => '_t', 'U' => '_u',
'V' => '_v', 'W' => '_w', 'X' => '_x', 'Y' => '_y', 'Z' => '_z' ) );
return $string;
}
|
Nur als Hinweis: Mit der Funktion bekommst du Probleme, sobald Akronyme durchgehend großgeschrieben werden: XMLParser wird zu x_m_l_parser statt xml_parser.
Mein (neuer) Ansatz sieht so aus:
PHP-Code:
// am Beispiel XMLParser bzw. XmlParser
static public function underscore($word)
{
// Namespaces durch Slash ersetzen; besser noch DIRECTORY_SEPARATOR
$word = str_replace('::', '/', $word);
// XMLParser wird zu XML_Parser
$word = preg_replace('/(?<=[A-Z])([A-Z]+)([A-Z][a-z])/', '\\1_\\2', $word);
// Jedem Großbuchstaben, der auf einen Kleinbuchstaben folgt, wird
// ein Unterstrich vorangesetzt
// XmlParser wird zu Xml_Parser
$word = preg_replace('/(?<=[a-z])([A-Z])/', '_\\1', $word);
return strtolower($word);
}
Das Ganze ist natürlch auch ohne Lookbehind machbar, allerdings erscheint es mir für den Moment am elegantesten, auch wenn ich mir noch nicht 100%ig sicher bin. Ich bin also offen für Belehrungen.
Grüße
|
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
|
| Themen-Optionen |
|
|
| Thema bewerten |
|
|
Forumregeln
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
|
PHP News
|