[PHP] return object in constructor werkt niet

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik wil een object in een constructor returnen, maar dit werkt niet.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
class quickie {

    public function quickie ($obj) {

        $strPathQuickies = PATH_LIB . '/quickie/';
        
        if (is_file($f = $strPathQuickies . $obj . '.php')) {
            require_once $f;
            return new $obj;
        }
    }
}


Ergens doe ik dus:

PHP:
1
$quickie = new quickie('form');


Dan wil ik dus gereturned krijgen de class in $obj.php zeg maar, maar ipv daarvan hou ik gewoon de quickie class.

Weet iemand iets dat ik over het hoofd zie? :)

edit: beveiliging zit verder wel goed, heb het voorbeeld beetje ingekort.
edit2: heb die '$this hack' al geprobeerd

[ Voor 12% gewijzigd door Verwijderd op 20-05-2007 01:22 ]


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Je moet niet quickie pakken als constructor gelijk bij java, maar __construct :)

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
MOET niet maar kan wel ;) Ja, ik weet php5 enzo maar vind het zo lelijk staan :P

Maar annyhowz dat maakt natuurlijk geen verschil he

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Een constructor zal -altijd- het net aangemaakte object (in dit geval quickie) returnen. Krijg je hier trouwens geen notice van ofzo? Een constructor hoort namelijk niets te returnen.

[ Voor 6% gewijzigd door Grijze Vos op 20-05-2007 01:07 ]

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Nope, geen notice. Hoe stel je voor dat ik dit dan doe, kan wel in de constructor een var aanmaken en die dan extern oppakken, maar heb liever dat het gaat werken zoals boven beschreven

^ zo maar opgelost.

[ Voor 8% gewijzigd door Verwijderd op 20-05-2007 02:24 ]


Acties:
  • 0 Henk 'm!

  • PowerSp00n
  • Registratie: Februari 2002
  • Laatst online: 19-08 08:24

PowerSp00n

There is no spoon

Ik denk dat jij meer zoekt naar de autoload mogelijkheid: http://nl3.php.net/autoload ?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Nee, ook dat zou het object niet vanuit de constructor returnen.

Heb het alsvolgt maar opgelost:

PHP:
1
2
3
4
5
6
7
    $quickie = new quickie('form');
        
    $quickie->obj->new_element('input', array(
        'label' => 'Username',
        'type' => 'text',
        'name' => 'username'
    ));


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class quickie {

    ## xtemplate object
    private $xtpl;
    ## html object
    public $obj;

    public function quickie ($obj) {

        $strPathQuickies = PATH_LIB . '/quickie/';

        if (is_file($f = $strPathQuickies . $obj . '.php')) {
            require_once $f;
            $this->obj = new $obj;
        }
    }
}

Acties:
  • 0 Henk 'm!

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Volgens mij is dit een typisch geval van de Factory Method ;)

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


Acties:
  • 0 Henk 'm!

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50

BikkelZ

CMD+Z

Geen idee wat je wil bereiken. Een contstructor maakt altijd een nieuwe instantie van het object aan.

Ben jij niet gewoon heel erg op zoek naar een singleton methode voor PHP (een instantie maximaal van een object)?

iOS developer


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

(jarig!)
BikkelZ schreef op zondag 20 mei 2007 @ 11:05:
Ben jij niet gewoon heel erg op zoek naar een singleton methode voor PHP (een instantie maximaal van een object)?
Nee, hij is op zoek naar een factory pattern/method/constructie, dat probeert ie iig te maken ;)
Singleton is iets heel anders, hoewel je je factory wel zo kan maken die ie ook singleton's produceert.

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Als je het dan zo oplost:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class quickie {

    function __construct ($obj) {

        $this->obj = $obj;
    }

    public function get_object () {

        $strPathQuickies = PATH_LIB . '/quickie/';
        
        if (is_file($f = $strPathQuickies . $this->obj . '.php')) {
            require_once $f;
            return new $this->obj;
        }
    }
}


En dan:

PHP:
1
2
$quickie = new quickie('form');
$quickie = $quickie->get_object();

Acties:
  • 0 Henk 'm!

Verwijderd

Wanneer je een classe zeg maar wilt uitlezen, kort door de bocht, wordt uit de klasse de magic function __toString() aangeroepen (indien aanwezig). Ik denk dat je daar eens mee moet prutsen dmv overriden.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
class test{
    private $holder;

    public function __construct($value){
        $this->holder = $value;
    }
    public function __toString(){
       return $this->holder;
    }
}

$instance = new test('Hallo');
echo $instance;      //  'Hallo'


Edit:
Jammer, toString returned expliciet strings en geen objecten. __autoLoad() lijkt me de oplossing voor jouw probleem.

[ Voor 11% gewijzigd door Verwijderd op 20-05-2007 14:49 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
mithras schreef op zondag 20 mei 2007 @ 11:37:
Als je het dan zo oplost:
PHP:
1
code...


En dan:

PHP:
1
2
$quickie = new quickie('form');
$quickie = $quickie->get_object();
Dit maakt natuurlijk niet zo heel veel verschil met hoe ik het nu heb he :)
Verwijderd schreef op zondag 20 mei 2007 @ 14:21:
Wanneer je een classe zeg maar wilt uitlezen, kort door de bocht, wordt uit de klasse de magic function __toString() aangeroepen (indien aanwezig). Ik denk dat je daar eens mee moet prutsen dmv overriden.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
class test{
    private $holder;

    public function __construct($value){
        $this->holder = $value;
    }
    public function __toString(){
       return $this->holder;
    }
}

$instance = new test('Hallo');
echo $instance;      //  'Hallo'
En deze returned dan ook strings, objects doet ie niet :)
Infinitive schreef op zondag 20 mei 2007 @ 09:24:
Volgens mij is dit een typisch geval van de Factory Method ;)
Voor zover ik er uit kan halen: jep dat klopt, maar hoe op te lossen?


Ik lees alwel op meerdere sites dat het gewoon niet mogelijk is om een object te returnen in een constructor. Manier die ik hier boven opgeef is dan denk ik kortste klap.

Tnx, voor alle replies alvast _/-\o_

[ Voor 21% gewijzigd door Verwijderd op 20-05-2007 14:56 ]


Acties:
  • 0 Henk 'm!

  • _Sunnyboy_
  • Registratie: Januari 2003
  • Laatst online: 19-09 14:58

_Sunnyboy_

Mooooooooooooooooo!

Zoals al eerder gezegd: Factory Method

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php 
class quickie { 

    public function createObject($objname) { 

        $strPathQuickies = PATH_LIB . '/quickie/'; 
         
        if (is_file($f = $strPathQuickies . $objname . '.php')) { 
            require_once $f; 
            return new $obj; 
        } 
    } 
} 
?>


En dan:

PHP:
1
2
3
<?
$quickie = Quickie::createObject('form');
?>

Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Als ik dat doe krijg ik een E_STRICT error
code:
1
Non-fatal error: Non-static method quickie::create() should not be called statically, assuming $this from incompatible context (# 2048)


Uiteraard is hij niet critical dus kan em wel supressen, maar liever niet.

Acties:
  • 0 Henk 'm!

  • Morax
  • Registratie: Mei 2002
  • Laatst online: 20-09 00:30
Probeer dan de functie eens hierin te wijzigen:

PHP:
1
2
3
public static function createObject($objname){

}


(Het gaat hier vooral om de toevoeging van het woord "static" in de functie declaratie ;) )

[ Voor 5% gewijzigd door Morax op 20-05-2007 15:57 ]

What do you mean I have no life? I am a gamer, I got millions!


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Oh, en het werkte in the first place al niet :P
Even voor de duidelijkheid, dit is wat ik nu heb:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
class quickie {

    public static function create ($obj) {
        $strPathQuickies = PATH_LIB . '/quickie/';
        if (is_file($f = $strPathQuickies . $obj . '.php')) {
            require_once $f;
            return new $obj;
        }
    }
}

$quickie = quickie::create('form');

[ Voor 14% gewijzigd door Verwijderd op 20-05-2007 16:18 ]


Acties:
  • 0 Henk 'm!

Verwijderd

wat werkt er precies niet?

Het zou moeten werken, weet je zeker dat het bestand bestaat etc ?

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Verwijderd schreef op zondag 20 mei 2007 @ 14:54:
[...]


Dit maakt natuurlijk niet zo heel veel verschil met hoe ik het nu heb he :)
Maar jij moet nu werken met $quickie->obj, in plaats van (wat je eigenlijk wil) $quickie. Als je nu al lappen code hebt gebaseerd op $quickie, zou je dat allemaal moeten veranderen. Met mijn "methode" niet :)
Ik lees alwel op meerdere sites dat het gewoon niet mogelijk is om een object te returnen in een constructor. Manier die ik hier boven opgeef is dan denk ik kortste klap.
Hoewel die warning niet expliciet op php.net vermeld staat heb je afaik wel gelijk :)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Verwijderd schreef op zondag 20 mei 2007 @ 16:31:
wat werkt er precies niet?

Het zou moeten werken, weet je zeker dat het bestand bestaat etc ?
Zegt gewoon dat ie de method niet kan vinden.
mithras schreef op zondag 20 mei 2007 @ 16:37:
[...]
Maar jij moet nu werken met $quickie->obj, in plaats van (wat je eigenlijk wil) $quickie. Als je nu al lappen code hebt gebaseerd op $quickie, zou je dat allemaal moeten veranderen. Met mijn "methode" niet :)
Kan ik natuurlijk ook gewoon er onder zetten:
PHP:
1
$quickie = $quickie->obj;

:)

[ Voor 45% gewijzigd door Verwijderd op 20-05-2007 17:48 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Dit topic is alweer een maandje oud, maar in de tussentijd had ik het gevoel dat het wel moet kunnen wat de topicstarter wilt bereiken, wat voor ons alsnog onbekend is of dit al is bereikt.. Vandaar dat ik mijn oplossing toch nog even post.

Het idee is om enkele magic functions te overloaden. Ik heb in dit voorbeeld hiervoor een klasse genaamd Proxy, welke als tussenlaag dient tussen de klasse en de scope waarvandaan je call-ed. Bij dat laatste dient de proxy genegeerd te worden. Zie tweede code voorbeeld:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Proxy{

    private $obj_class = NULL;
    
    public function __construct($className){
        $this->obj_class = new $className;
    }
    
    public function __call($funcName, $args){
        for($num = 0, $args_vars = array(); $num < count($args); $num++)
            $args_vars[] = '$args['.$num.']';

        eval('return $this->obj_class->$funcName(' . implode(", ", $args_vars) . ');');
    }

    public function __get($var){
        return $this->obj_class->$var;
    }
    
    public function __set($var, $val){
        $this->obj_class->$var = $val;
    }
    
    public function __isset($var){
        return isset($this->obj_class->$var);
    }
    
    public function __unset($var){
        unset($this->obj_class->$var);
    }

    public function __destruct(){
        unset($this->obj_class);
    }

    
}


Gebruik:
PHP:
1
2
3
4
5
6
7
    $obj = new Proxy("MijnTestKlasse");   
    $obj->test(1, 2, 3);     // functie uit MijnTestKLasse

    $obj->varA = 1;          // var uit MijnTestKlasse,  etc
    echo $obj->varA."<br>";
    $obj->varA = 2;
    echo $obj->varA."<br>";

[ Voor 6% gewijzigd door Verwijderd op 25-06-2007 22:30 ]


Acties:
  • 0 Henk 'm!

  • Shadowman
  • Registratie: Januari 2002
  • Niet online
$obj->test("test 'enzo"); < je wil niet dat er userinput bij die functies wordt meegegeven.

Het Factory-pattern (in dit topic al een aantal keer genoemd: wikipedia: Factory Method) is geschikt voor wat je nu op een (mijns insziens) nog al aparte manier oplost.
Pagina: 1