php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Entwicklung > PHP Developer Forum
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

 

 


PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Fragen zu Laravel, YII oder anderen PHP-Frameworks.

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1 (permalink)  
Alt 12-12-2006, 00:21
GELight
 Registrierter Benutzer
Links : Onlinestatus : GELight ist offline
Registriert seit: Sep 2004
Beiträge: 243
GELight ist zur Zeit noch ein unbeschriebenes Blatt
GELight eine Nachricht über ICQ schicken
Standard [PHP5] kleine Frage zum includieren..

Nabend alle zusammen,

Ich habe in einem beliebigen Verzeichnis beliebig viele PHPs, in denen ich derzeit zum Test verschiedene Objekte initialisiere bzw. deklariere.
Diese Dateien sollen automatisch in mein System includiert und somit ausgeführt werden. ( also die Scripte darin )

Nun hab ich zum Test ein statisches include ausgeführt...
PHP-Code:
include( "verzeichnis/init.php" ); 
.. dies funktioniert wunderbar. Er führt alles aus, was ich will und ich hab im weiteren Code Zugriff auf die erzeugten Objekte.

Nun möchte ich sämtliche Dateien in diesem verzeichnis bzw. dessen unterordner und deren *.phps automatisch includieren.
Dafür habe ich eine Funktion geschrieben, die das erledigt. Sie funktioniert sogar tatellos... Ich habe zum Test mal in jede der PHPs ein Echo gelegt um zu sehen, ob er alles findet und ausführt.
Das komische ist nun, dass er zwar die dateien finden und die Echos ausgibt aber meine Objekte werden nicht initialisiert.

Woher kann das kommen?
Die Funktion, die alles includiert schaut so aus:
PHP-Code:
function include_dir_php$folder )
{
    
$handle  realpath$folder );
    if (
$handle == false){

        echo 
"Der Pfad: \"<b>".$folder."</b>\" existiert nicht<br>";

    }else{
    
        
$handle opendir $handle ); 
        while (
$file readdir ($handle))
        {
            
// Dateindung herausfinden
            
$dateiendung pathinfo$file );
            
$dateiendung $dateiendung["extension"] ;
                    
            if ( 
is_dir(realpath($folder)."/".$file) && $file != "." && $file != ".." ){                    

                
include_dir_phprealpath$folder )."/".$file );                

            }
                        
            if (
$dateiendung == "php" ){    

                
//require_once ( realpath($folder)."/".$file );                
                
include ( realpath($folder)."/".$file );

            }

        }

    }


Mario
Mit Zitat antworten
  #2 (permalink)  
Alt 12-12-2006, 00:29
3DMax
 PHP Senior
Links : Onlinestatus : 3DMax ist offline
Registriert seit: Jan 2004
Beiträge: 1.916
3DMax ist zur Zeit noch ein unbeschriebenes Blatt
Standard Re: [PHP5] kleine Frage zum includieren..

Zitat:
Original geschrieben von GELight
Das komische ist nun, dass er zwar die dateien finden und die Echos ausgibt aber meine Objekte werden nicht initialisiert.
welche objekte, wo sollen diese erzeugt werden?
Mit Zitat antworten
  #3 (permalink)  
Alt 12-12-2006, 00:51
penizillin
 PHP Guru
Links : Onlinestatus : penizillin ist offline
Registriert seit: Feb 2004
Beiträge: 10.166
penizillin ist zur Zeit noch ein unbeschriebenes Blatt
Standard

meinst du soetwas?

b.php
PHP-Code:
$foo = new FooClass(); 
a.php
PHP-Code:
function incl(){ include 'b.php'; }

incl();
echo 
$foo->some_method(); 
selbstverständlich ist $foo außerhalb von incl() nicht bekannt.
Mit Zitat antworten
  #4 (permalink)  
Alt 12-12-2006, 00:54
GELight
 Registrierter Benutzer
Links : Onlinestatus : GELight ist offline
Registriert seit: Sep 2004
Beiträge: 243
GELight ist zur Zeit noch ein unbeschriebenes Blatt
GELight eine Nachricht über ICQ schicken
Standard [PHP5] include

Aber natürlich.... du hast ja Recht... hmmm.
Das hatte ich ja voll vegessen in meinem Schreibwahn..
Ist ja innerhalb der Funktion alles.

Hmm, wie könnte ich denn sonst mein verzeichnis auslesen lassen, die Objekte initialisieren und nach außen hin freigeben?

Ich könnte es statisch includieren aber dann müsste ich meine Klassenaufrufe alle in eine Datei legen und das kann auf Dauer sehr viel werden...

Mario
Mit Zitat antworten
  #5 (permalink)  
Alt 12-12-2006, 00:56
Griecherus
 PHP Senior
Links : Onlinestatus : Griecherus ist offline
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
Griecherus ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Eine mögliche Lösung ist beispielsweise:
PHP-Code:
$GLOBALS['obj'] = new classname(); 
Das würde das Problem des Gültigkeitsbereichs umgehen...
Mit Zitat antworten
  #6 (permalink)  
Alt 12-12-2006, 00:57
penizillin
 PHP Guru
Links : Onlinestatus : penizillin ist offline
Registriert seit: Feb 2004
Beiträge: 10.166
penizillin ist zur Zeit noch ein unbeschriebenes Blatt
Standard

verzichte doch einfach auf die funktionsdeklaration (mit anderen worten, baue den code block einfach an der stelle ein, an der du die includes brauchst; ganz ganz häßlich solches massen-inkludieren...)
Mit Zitat antworten
  #7 (permalink)  
Alt 12-12-2006, 01:02
GELight
 Registrierter Benutzer
Links : Onlinestatus : GELight ist offline
Registriert seit: Sep 2004
Beiträge: 243
GELight ist zur Zeit noch ein unbeschriebenes Blatt
GELight eine Nachricht über ICQ schicken
Standard [PHP5] include

@Griecherus,

Dann müsste ich später immer über $GLOBALS['obj'] auf mein Object zugreifen richtig? Hmm... Dazu ist doch ein "umgehen" immer nicht wirklich schön oder?

@penizillin,

Gerade das statische in den Code einbauen wollte ich irgendwie vermeiden, da ich sowas alles möglichst dynamisch halten möchte.
Mit anderen Worten: das System soll das alles im Hintergrund erledigen, sodass ich da nichts mehr anrühren brauche.

Aber was spricht denn gegen ein automatisches includieren?
Ob ich 20x untereinander include( "xyz.php" ); stehen habe oder das ganze über eine Funktion löse ist doch in dem Fall egal oder nicht?

Mario
Mit Zitat antworten
  #8 (permalink)  
Alt 12-12-2006, 01:11
3DMax
 PHP Senior
Links : Onlinestatus : 3DMax ist offline
Registriert seit: Jan 2004
Beiträge: 1.916
3DMax ist zur Zeit noch ein unbeschriebenes Blatt
Standard

GELight, habe immer noch nicht so richtig verstanden, was du da vorhast.

wenn's dir aber um dynamischen include für klassen-deklaration geht, kannst du auch __autoload() benutzen.
Mit Zitat antworten
  #9 (permalink)  
Alt 12-12-2006, 01:18
GELight
 Registrierter Benutzer
Links : Onlinestatus : GELight ist offline
Registriert seit: Sep 2004
Beiträge: 243
GELight ist zur Zeit noch ein unbeschriebenes Blatt
GELight eine Nachricht über ICQ schicken
Standard [PHP5] include

Hallo 3DMax,

Ich möchte eigentlich genau das machen, was penizillin in seiner ersten Antwort so schön veranschaulicht hat.
In einem Verzeichnis liegen PHPs, in denen ich nur die initialisierung und/oder auch die deklarierungen zu einem erstellten Objekt stehen habe.

Und dieses Verzeichnis möchte ich dynamisch durchlaufen und sämtliche Klassen bzw. Objekte erstellen lassen, da ich später damit arbeiten möchte. Das ganze aber möglichst dynamisch alles, da ich nicht immer das includieren statisch per hand schreiben will.

Es soll sozusagen an einer Stelle im System Dateien geben, in der ich meine Objecte erstellen lasse... an ander ganz anderen Stelle will ich mit diesen arbeiten.

Ich wüsste nicht, wie ich es jetzt noch genauer beschreiben kann, was ich machen will.

Mario
Mit Zitat antworten
  #10 (permalink)  
Alt 12-12-2006, 01:20
Griecherus
 PHP Senior
Links : Onlinestatus : Griecherus ist offline
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
Griecherus ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Lies dir das mal durch zum Thema autoload.
Mit Zitat antworten
  #11 (permalink)  
Alt 12-12-2006, 01:32
GELight
 Registrierter Benutzer
Links : Onlinestatus : GELight ist offline
Registriert seit: Sep 2004
Beiträge: 243
GELight ist zur Zeit noch ein unbeschriebenes Blatt
GELight eine Nachricht über ICQ schicken
Standard [PHP5] include

Hab das eben schon gelesen als es 3DMax gepostet hatte.
Ich werd mir das wohl nochmal durch den Kopf gehen lassen alles.

Wobei meineigentliches Problem ja nicht das aufrufen einer nicht existirenden Klasse ist. Okay.. klar es kommt natürlich genau zu diesem Fehler bzw. dieser Situation, dass meine Klassen oder bzw. Objekte noch nicht vorhanden sind, wenn ich versuche darauf zuzugreifen. Da ich meine Deklerationen am Objekt auch in diesen Dateien machen möchte, geht das nicht mit dieser Funktion.
Diese ruft ja einfach nur eine PHP auf, die den selben Namen wie die Klasse selbst hat, haben muss und führt die Klasse aus.

Ich habe aber völlig verschiedene Konstruktoren. Die eine Klasse braucht oder verlangt nach einem Parameter im Konstruktor... die nächste nicht.. die dritte wieder mehrere usw...

Ich verstehe die Funktionsweise dieser kleinen... ich sag mal... Hilfsfunktion von PHP aber gefallen tuts mir nicht.

Wenn, dann möchte ich schon sicherstellen, dass die komplette Datenverarbeitung vorher stattfindet... sprich: aufrufen der PHPs... ausführen meiner Klassen und dann erst gehts weiter zur zB. Ausgabe von allem.

Ich hoffe ihr könnt mir folgen. Ich denke aber schon oder?

Mario
Mit Zitat antworten
  #12 (permalink)  
Alt 12-12-2006, 02:34
Griecherus
 PHP Senior
Links : Onlinestatus : Griecherus ist offline
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
Griecherus ist zur Zeit noch ein unbeschriebenes Blatt
Standard Re: [PHP5] include

Zitat:
Original geschrieben von GELight
Hab das eben schon gelesen als es 3DMax gepostet hatte.
Ich werd mir das wohl nochmal durch den Kopf gehen lassen alles.

Wobei meineigentliches Problem ja nicht das aufrufen einer nicht existirenden Klasse ist. Okay.. klar es kommt natürlich genau zu diesem Fehler bzw. dieser Situation, dass meine Klassen oder bzw. Objekte noch nicht vorhanden sind, wenn ich versuche darauf zuzugreifen. Da ich meine Deklerationen am Objekt auch in diesen Dateien machen möchte, geht das nicht mit dieser Funktion.
Diese ruft ja einfach nur eine PHP auf, die den selben Namen wie die Klasse selbst hat, haben muss und führt die Klasse aus.

Ich habe aber völlig verschiedene Konstruktoren. Die eine Klasse braucht oder verlangt nach einem Parameter im Konstruktor... die nächste nicht.. die dritte wieder mehrere usw...

Ich hoffe ihr könnt mir folgen. Ich denke aber schon oder?

Mario
Ich glaube da hast du etwas falsch verstanden. Dass du Konstruktoren hast, die natürlich voneinander abweichen können, was zu übergebende Parameter angeht, krazt Autoloading reichlich wenig. Was __autoload tut, ist Folgendes:
PHP-Code:

// a.class.php
class a
{
    public function 
__construct($test_param)
    {
        echo 
$test_param// nur zum testzweck
    
}
}

// irgendeine andere datei

function __autoload($classname)
{
    require_once 
$classname '.class.php';
}

$obj = new a('ich bin ein parameter, der dem konstruktor uebergeben wird'); 
__autoload wird automatisch aufgerufen, sobald du versuchst, eine Klasse (in diesem Fall die Klasse a) zu benutzen, die noch nicht instanziiert wurde - und versucht, diese zu laden (siehe Funktion). Wie viele Parameter du welcher Klasse übergibst, ist dabei belanglos. Du wirst, was das angeht, also nicht eingeschränkt.
Das müsste eigentlich genau das sein, wonach du suchst.

Geändert von Griecherus (12-12-2006 um 02:38 Uhr)
Mit Zitat antworten
  #13 (permalink)  
Alt 12-12-2006, 13:41
GELight
 Registrierter Benutzer
Links : Onlinestatus : GELight ist offline
Registriert seit: Sep 2004
Beiträge: 243
GELight ist zur Zeit noch ein unbeschriebenes Blatt
GELight eine Nachricht über ICQ schicken
Standard [PHP5] include

Hmm... also danke nochmal für die Erklährung. Das ist schon ganz interessant so. Ich denke, dass ich die Funktion ansich jetzt schon verstanden habe.

Einen kleinen Unterschied habe ich aber dennoch, wenn ich mir das so anschaue. Die __autoload ruft doch meine Klasse auf, wenn diese noch nicht initialisiert ist oder? Ich möchte aber direkt danach bestimmte Parameter in der Klasse über weitere Methoden setzen lassen.
Das bedeutet ich will nicht nur über __autoload förmlich den Konstruktor ausführen lassen....

Moment.. ich zeig euch nochmal am besten meinen Aufbau, wie ich ihn habe und wie ich mir das vorgestellt habe. Wie gesagt... mit der statischen includierung funktionierts ja.... das Problem derzeit lag ja eigentlich nur daran, dass meine Objecte nur in der Funktion erreichbar waren, wie penizillin schon geschrieben hatte.

ROOT Verzeichnis: cms.php
In der cms.php führe ich in dem Fall 2 Aktionen aus.

1. includieren aller Dateien aus dem INIT verzeichnis und ausführen der Codes...
2. Ausführen und darstellen des Templates vom CMS. ( das steht alles schon... ich brauch hier dann halt den zugriff auf die Klassen.
Als Beispiel könnte in den kommenden Dateien irgendwo ein:
PHP-Code:
$tab1->show(); 
... stehen, welches ja nur noch eine Methode der Klasse ausführt.
Ich will also hier nicht erst die Klasse aufrufen.

INIT Verzeichnis mit allen PHPs und den Klassenaufrufen.
dies hier wäre ein Beispiel, was dort drin stehen kann:
PHP-Code:
    $tab1 = new tab"tabnane1" );
    
$tab1->set_content_style"padding: 20px;" );
    
$tab1->set_skin$skin );
    
$tab1->add_reiter"Ansicht""administration/admin_test3.php"$skin."cms_dir_open.gif"false );
    
$tab1->add_reiter"Bearbeiten 1""administration/admin_test1.php"$skin."cms_file_root.gif"true );
    
$tab1->add_reiter"Files""administration/admin_test1.php"$skin."cms_cut.gif"false );
    
$tab1->add_reiter"Optioinen""administration/admin_test2.php"$skin."admin_edit.gif"false );
    
$tab1->add_reiter"Downloads"""$skin."cms_download.gif"false );
    
$tab1->add_reiter"Help"""$skin."cms_help.gif"false ); 
...Hier sollen also die Klassen ausgeführt werden UND bestimmte Parameter dafür gesetzt werden.

Ich will sozusagen einfach nur die möglichst absolute Trennung zwischen dem initialisieren + vergabe der Eigenschaften und der Darstellung schaffen.
Daher möchte ich in meinen reinen Admindateien im Normalfall nichts vonwegen $test = new test(); stehen haben... das soll alles schön getrennt passieren. ( vergessen wir hier einfach mal verschachtelte Klassen ). Erstmal nur das hier.... und gehen muss es oder etwa nicht? Oder bin ich etwa immernoch auf dem totalen Holzweg?

Mario
Mit Zitat antworten
  #14 (permalink)  
Alt 12-12-2006, 13:56
Griecherus
 PHP Senior
Links : Onlinestatus : Griecherus ist offline
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
Griecherus ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Um ehrlich zu sein erkenne ich da keinen Grund, kein __autoload zu benutzen. Ich glaube ich kann nicht nachvollziehen, wieso man die Initialisierung einer Klasse unbedingt strikt von jeglichen Methodenaufrufen trennen möchte, aber das liegt natürlich bei dir. Schließt du autoloading aus, bleiben eigentlich nur die - bereits erwähnten - Möglichkeiten $GLOBALS zu benutzen oder die Klassen entweder statisch zusammen oder einzeln genau dort zu includen, wo du sie brauchst - und das dürfte für dich ja eigentlich entfallen.
Die "saubersten" Lösungen sind leider genau die, die du ausschließt.

Geändert von Griecherus (12-12-2006 um 14:08 Uhr)
Mit Zitat antworten
  #15 (permalink)  
Alt 12-12-2006, 15:33
closure
 Master
Links : Onlinestatus : closure ist offline
Registriert seit: Mar 2006
Beiträge: 796
closure ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Hi,
ich halte es für keine gute lösung aber man könnte folgendes machen.
Du gehst in etwa den weg den man auch mit shared libs geht.
Jedes deiner init-scripte tut was es tun muss initialisiert die klasse und
gibt dann das objekt über eine einheitliche init-funktion zurück. Das wäre
ein äquivalent zum sharelib einsprungpunkt. Als einfache konvention könnte
die funktion dateiname_init() heissen. Dann packst du das laden der
ganzen geschichte in eine klasse, damit du das GLOBALS-problem los wirst.
Dann noch eine convenience-methode um an die objekt zu kommen
und du kannst relativ schmerzfrei arbeiten.

Das könnte folgendermaßen aussehen.
Nehmen wir an du hast folgende init-dateien im verzeichnis '/home/user/init'

foo.php
PHP-Code:
class Foo{
   private 
$val_;
   public function 
__construct($val){
        
$this->val_ $val;
   }
  public function 
inspect(){
      return 
$this->val_;
  }
}

function 
foo_init(){
   return new 
Foo('foo');

bar.php
PHP-Code:
class Bar{
   private 
$val_;
   public function 
__construct($val){
        
$this->val_ $val;
   }
  public function 
inspect(){
      return 
$this->val_;
  }
}

function 
bar_init(){
   return new 
Bar('bar');

Dann könnte der rest so aussehen:
PHP-Code:
<?php

error_reporting
(E_ALL);

interface 
Visitor{
  public function 
visit($obj);
}
interface 
Visitable{
  public function 
accept(Visitor $obj);
}

class 
LibFile implements Visitable{
    private 
$path_;
    private 
$init_func_;
    private 
$class_name_;
    
    public function 
__construct($path_str,$suffix){
    
$this->path_ $path_str;
    
$fname basename($this->path_);
    if(!
$this->ends_with($fname,'.php'))
      throw new 
Exception('missmatch');
    
$this->class_name_ strtolower(substr($fname,0,strlen($fname) - 4));
    
$this->init_func_ $this->class_name_.$suffix;
    }
    
    public function 
accept(Visitor $visitor){
      
$visitor->visit($this);
    }
    
    public function 
file_name(){
      return 
$this->path_;
    }

    public function 
init_func(){
      return 
$this->init_func_;
    }

    public function 
class_name(){
      return 
$this->class_name_;
    }

    protected function 
ends_with($what,$with){
      return 
substr($what,strlen($what) - strlen($with)) == $with true false;
    }
}

class 
SLibLoader implements Visitor{
    private 
$target_;
    public function 
__construct($target){
        
$this->target_ $target;
    }
    public function 
visit($file){
        require_once(
$file->file_name());
        
$this->target_->add($file->class_name(),call_user_func($file->init_func()));
    }
}

class 
CMSEnv{
    private 
$instances_;
    private 
$visitor_;
    public function 
__construct($dir,$init_suffix '_init'){
     
$this->instances_ = array();
     
$this->visitor_ = new SlibLoader($this);
     
$this->include_slibs(realpath($dir),$init_suffix);
    }

    public function 
add($name,$obj){
      
$this->instances_[$name] = $obj;
    }

    protected function 
include_slibs($the_dir,$suffix){
    
$d dir($the_dir);
    while(
false !== ($cur $d->read())){
      if(
$cur !== '.' && $cur !== '..' && is_dir($the_dir.'/'.$cur)){
          
$this->include_slibs($the_dir.$cur.'/',$suffix);
      }else{
        try{
        
$lib = new LibFile($the_dir.'/'.$cur,$suffix);
        
$lib->accept($this->visitor_);
        }catch(
Exception $ex){
        
//file did not match
        //just go on
        
}
      }
    }
    }

    public function 
__get($name){
    if(!isset(
$this->instances_[$name]))
      return 
null;
    return 
$this->instances_[$name];
    }
}
Das ganze genutzt via:
PHP-Code:
$cms = new CMSEnv('/home/user/init/');
print 
$cms->foo->inspect()."\n";
print 
$cms->bar->inspect()."\n"
Ausgabe:
Code:
foo
bar
HTH

greets
__________________
(((call/cc call/cc) (lambda (x) x)) "Scheme just rocks! and Ruby is magic!")

Geändert von closure (12-12-2006 um 15:57 Uhr)
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 

Themen-Optionen
Thema bewerten
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.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an


PHP News

Die RIGID-FLEX-Technologie
Die RIGID-FLEX-TechnologieDie sogenannte "Flexible Elektronik" , oftmals auch als "Flexible Schaltungen" bezeichnet, ist eine zeitgemäße Technologie zum Montieren von elektronischen Schaltungen.

06.12.2018 | Berni

ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlicht
ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlichtDie bekannte Marktplatzsoftware ebiz-trader ist in der Version 7.5.0 veröffentlicht worden.

28.05.2018 | Berni


 

Aktuelle PHP Scripte

Newsmanager

Der Newsmanager ist ein Newssystem und Newsletter in einem. Mit WYSIWYG Editor und E-Mail import aus einer bestehenden MySql Datenbank sowie dynamische Kategorien / Themen Filter.

11.09.2019 Stephan_1972 | Kategorie: PHP/ News
Modelmanager

Der Modelmanager ist ein Webtool für Fotografen, kann als komplette Homepage oder als Webtool installiert werden.

11.09.2019 Stephan_1972 | Kategorie: PHP/ Webservice
ContentLion - Open Source CMS ansehen ContentLion - Open Source CMS

ContentLion ist ein in PHP geschriebenes CMS, bei dem man Seiten, Einstellungen usw. in Ordnern lagern kann

22.08.2019 stevieswebsite2 | Kategorie: PHP/ CMS
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 10:25 Uhr.