Hi PHP-hulpers,

Ik heb een parent class die doormiddel van een private methode een andere child class aanmaakt. De child class extends de parent class.

Vervolgens voer ik in de child class een methode uit die gedefineerd wordt in de parent class. In die methode wordt een property gebruikt uit de parent class die in de __construct van de parent class wordt ingesteld op: $this->ch = curl_init();

Eerder genoemde methode (gedefineerd in de parent class) gebruikt $this->ch voor het uitvoeren van een aantal curl_exec's. Wanneer ik de methode echter probeer uit te voeren krijg ik de foutmelding dat $this->ch = NULL en dus !niet een resource voor curl is. Dit blijkt ook wanneer ik in de child class var_dump($this->ch); uitvoer.

Hoe kan ik de methode uit de parent class toch gewoon gebruiken in de child class?
parent::__construct uitvoeren in de child class is geen optie. Via een andere methode die in de __construct van de parent class wordt aangeroepen wordt namelijk de child class geladen. Oftewel, de child class wordt dan een tweede keer geïnitialiseerd en die ïnitialiseerd de child class weer enz., enz.
De $this->ch in de child class pas instellen op $this->ch = curl kan ook niet omdat in de parent class $this->ch al nodig is en $this->ch in de child class met deze curl_session moet draaien.

Hieronder nog even een (vereenvoudigde) weergave ter verduidelijking:

[size=120]parent.class.php[/size]
<?php
class Parent{
    protected $ch;

    function __construct(){
        $this->ch = curl_init();
        loadClass();
    }

    private function loadClass(){
        include('apps/'.$_GET['app'].'/lib/class.php');
        return new $_GET['app'];
    }

    public function curlGet($url){
        curl_setop($this->ch, CURLOPT_URL, $url);                     // error child.class.php verwijs naar deze lijn
        curl_setop($this->ch, CURLOPT_RETURNTRANSFER, true);  // error child.class.php verwijs naar deze lijn
        return(curl_exec($this->ch));
    }
}
?>

[size=120]child.class.php[/size]
<?php
class Child extends Parent{
    function __construct(){
        curlGet($url);    // error: PHP Warning:  curl_setopt() expects parameter 1 to be resource, null given in Parent.class.php on line 16 & 17
    }
}
?>


Ik hoop dat iemand me met bovenstaande vraag kan helpen.

Alvast bedankt voor jullie hulp en tijd,
Wilfred Dijksman
Ergens krijg ik het vermoeden dat je opbouw van de classes dus echt verkeerd is als je met dit soort problemen te maken krijgt. Een parent die een child maakt van zichzelf.... klinkt als onwenselijk (behalve als je gewoon een levend wezen bent dan).

Maar een mogelijke oplossing van je probleem.
Laat de construct niet direct die curl property aanmaken, maar een getter ervoor. Check in die getter of de variabele al is geinitialiseerd of niet en maak aan indien nodig:
<?php
class Parent{
private $ch;

protected function getCh(){
if ( $this->ch == null ){
$this->ch = curl_init();
}
return $this->ch;
}
}
?>
(een reden temeer om al je properties private te hebben en altijd op vragen via een getter)
Hi Erwin,

Ik moet inderdaad toegeven dat mijn code hoogst waarschijnlijk niet 'helemaal' optimaal is ;) (hobby/beginner (qua OOP)). De situatie zoals jij deze beschrijft (parent die een child maakt van zichzelf) doet zich gelukkig niet voor. De parent class heeft een methode die wordt aangeroepen via de __construct en die een nieuwe child class aanmaakt.

Over je mogelijke oplossing:
Probleem wordt dan dat er meerdere cUrl sessies komen omdat $this->ch dan twee keer wordt ingesteld op curl_init(); Voor de werking van het systeem is één dezelfde sessie in cUrl vereist (cUrl logt in de parent class in op een systeem en haalt in de child class data op uit datzelfde systeem. Dit moet in dezelfde cUrl sessie gebeuren omdat anders de login die cUrl heeft gedaan in de parent class verlopen is.).

Is het trouwens raar dat de property $this->ch; niet wordt mee genomen naar een child class (die ge-extends is)? Want als dat zo is moet de indeling veranderen en moet ik/we niet allemaal functies erbij gaan halen.

Overigens had ik over getters wel eens eerder gelezen. Ga ik in het vervolg op proberen te letten!

In ieder geval bedankt voor je hulp tot zover. Met de getters is mijn code er in ieder geval weer iets beter op geworden ;) Mocht je nog een idee hebben dan hoor ik het graag.

Met vriendelijke groet,
Wilfred Dijksman
Je moet wel bedenken dat een constructor van de parent niet automatisch wordt aangeroepen. Daarvoor gebruik je parent::__construct(); in de constructor van de child class.
Je moet wel bedenken dat een constructor van de parent niet automatisch wordt aangeroepen. Daarvoor gebruik je parent::__construct(); in de constructor van de child class.

Oh? Waar haal je dat vandaan?
Alleen als je zelf een constructor maakt in de child class, dus in dit geval wel. Hier override je de constructor, dus moet je de parent constructor wel callen in dit geval.
Wilfred Dijksman op 30/01/2013 22:30:30
Hoe kan ik de methode uit de parent class toch gewoon gebruiken in de child class?
parent::__construct uitvoeren in de child class is geen optie. Via een andere methode die in de __construct van de parent class wordt aangeroepen wordt namelijk de child class geladen. Oftewel, de child class wordt dan een tweede keer geïnitialiseerd en die ïnitialiseerd de child class weer enz., enz.


Zoals ik in me eerste post al schreef is het aanroepen van parent::__construct helaas geen oplossing.

In ieder geval bedankt voor het mee denken! Wel raar trouwens dat je de __construct overwrite als je child class ook een construct heeft. Het komt er in de praktijk dus op neer dat extends alleen maar de methodes en properties meeneem, maar niet de waarde van de properties die ze tijdens het initialiseren van de parent class al hebben gekregen. Laat dat nou net zijn wat ik wel nodig heb :(

Iemand nog een idee?

Met vriendelijke groet,
Wilfred Dijksman
Waarom is parent::__construct geen oplossing? Tevens vind ik het nog steeds vreemd dat de parent een child aanmaakt, maar goed je zal er vast goed over hebben nagedacht.

En er is niks vreemds aan, als je een method override wordt de oude method niet meer gebruikt.
@Wouter J
parent::__construct uitvoeren in de child class is geen optie. Via een andere methode die in de __construct van de parent class wordt aangeroepen wordt namelijk de child class geladen. Oftewel, de child class wordt dan een tweede keer geïnitialiseerd en die ïnitialiseerd de child class weer enz., enz. Zie ook mijn citaat in mijn vorige reactie en het voorbeeld hieronder:

parent.class.php

<?php
class Parent{
	function __construct(){
		loadChild($var);
	}

	function loadChild($nameClass){
		include('lib/'.$nameClass.'.class.php');
		return new $nameClass;
	}
}
?>


child.class.php

<?php
class Child extends Parent{
	function __construct(){
		parent::__construct
	}
}
?>


Sanenvattend: als ik parent::__construct gebruik komt het script in een soort van loop waarin hij telkens classes gaat aanmaken. Dit eindigt in een error: Cannot redeclare class Child.

De rede dat de parent een child aanmaakt is omdat afhankelijk van de app die geladen moet worden (via $_GET['app']) er een andere class geladen en geïnitialiseerd moet worden.

Ik hoop dat het verhaal zo een beetje duidelijk is. Vragen en/of mogelijk oplossingen hoor ik graag.

Met vriendelijke groet,
Wilfred Dijksman
Moet het dan perse een extension zijn?
Ja, het is een systeem wat meerdere modules/apps heeft die wel dezelfde basis functies nodig hebben. Die basis functies zitten in de parent class.

[size=xsmall]Toevoeging op 31/01/2013 15:10:14:[/size]

Ik heb ondertussen een oplossing voor mijn probleem:

Ik laad een variabele met daarin het parent class object in de child class zodat via die variabele alles toegankelijk is vanuit de child class. Zie ook het voorbeeld hieronder:

parent.class.php

<?php
class Parent{
	private $app;

	function __construct(){
		loadChild($var);
	}

	function loadChild($nameClass){
		include('lib/'.$nameClass.'.class.php');
		$this->app = new $nameClass($this);
	}

	function getSomething($what){
		return($what);
	}
}
?>


child.class.php

<?php
class Child{
	private $parent_object;

	function __construct($parent_object){
		$this->parent_object = $parent_object;

		// execute methode from Parent class
		$this->parent_object->getSomeThing;
	}
}
?>


Opmerking: Nadeel van deze methode is natuurlijk wel dat de visability van properties en methodes omzeilt wordt.

Mochten jullie nog opmerkingen / andere suggesties hebben dan hoor ik dat graag. Nogmaals dankt voor jullie meedenken tot zover.

Met vriendelijke groet,
Wilfred Dijksman

[size=xsmall]Toevoeging op 31/01/2013 15:12:03:[/size]

Ja, het is een systeem wat meerdere modules/apps heeft die wel dezelfde basis functies nodig hebben. Die basis functies zitten in de parent class.

[size=xsmall]Toevoeging op 31/01/2013 15:10:14:[/size]

Ik heb ondertussen een oplossing voor mijn probleem:

Ik laad een variabele met daarin het parent class object in de child class zodat via die variabele alles toegankelijk is vanuit de child class. Zie ook het voorbeeld hieronder:

parent.class.php

<?php
class Parent{
	private $app;

	function __construct(){
		loadChild($var);
	}

	function loadChild($nameClass){
		include('lib/'.$nameClass.'.class.php');
		$this->app = new $nameClass($this);
	}

	function getSomething($what){
		return($what);
	}
}
?>


child.class.php

<?php
class Child{
	private $parent_object;

	function __construct($parent_object){
		$this->parent_object = $parent_object;

		// execute methode from Parent class
		$this->parent_object->getSomeThing();
	}
}
?>


Opmerking: Nadeel van deze methode is natuurlijk wel dat de visability van properties en methodes omzeilt wordt.

Mochten jullie nog opmerkingen / andere suggesties hebben dan hoor ik dat graag. Nogmaals dankt voor jullie meedenken tot zover.

Met vriendelijke groet,
Wilfred Dijksman

[size=xsmall]Toevoeging op 31/01/2013 15:12:16:[/size]

Ja, het is een systeem wat meerdere modules/apps heeft die wel dezelfde basis functies nodig hebben. Die basis functies zitten in de parent class.

[size=xsmall]Toevoeging op 31/01/2013 15:10:14:[/size]

Ik heb ondertussen een oplossing voor mijn probleem:

Ik laad een variabele met daarin het parent class object in de child class zodat via die variabele alles toegankelijk is vanuit de child class. Zie ook het voorbeeld hieronder:

parent.class.php

<?php
class Parent{
	private $app;

	function __construct(){
		loadChild($var);
	}

	function loadChild($nameClass){
		include('lib/'.$nameClass.'.class.php');
		$this->app = new $nameClass($this);
	}

	function getSomething($what){
		return($what);
	}
}
?>


child.class.php

<?php
class Child{
	private $parent_object;

	function __construct($parent_object){
		$this->parent_object = $parent_object;

		// execute methode from Parent class
		$this->parent_object->getSomeThing();
	}
}
?>


Opmerking: Nadeel van deze methode is natuurlijk wel dat de visability van properties en methodes omzeilt wordt.

Mochten jullie nog opmerkingen / andere suggesties hebben dan hoor ik dat graag. Nogmaals dankt voor jullie meedenken tot zover.

Met vriendelijke groet,
Wilfred Dijksman

[size=xsmall]Toevoeging op 31/01/2013 15:12:44:[/size]

Ja, het is een systeem wat meerdere modules/apps heeft die wel dezelfde basis functies nodig hebben. Die basis functies zitten in de parent class.

[size=xsmall]Toevoeging op 31/01/2013 15:10:14:[/size]

Ik heb ondertussen een oplossing voor mijn probleem:

Ik laad een variabele met daarin het parent class object in de child class zodat via die variabele alles toegankelijk is vanuit de child class. Zie ook het voorbeeld hieronder:

parent.class.php

<?php
class Parent{
	private $app;

	function __construct(){
		loadChild($var);
	}

	function loadChild($nameClass){
		include('lib/'.$nameClass.'.class.php');
		$this->app = new $nameClass($this);
	}

	function getSomething($what){
		return($what);
	}
}
?>


child.class.php

<?php
class Child{
	private $parent_object;

	function __construct($parent_object){
		$this->parent_object = $parent_object;

		// execute methode from Parent class
		$this->parent_object->getSomeThing();
	}
}
?>


Opmerking: Nadeel van deze methode is natuurlijk wel dat de visability van properties en methodes omzeilt wordt.

Mochten jullie nog opmerkingen / andere suggesties hebben dan hoor ik dat graag. Nogmaals dankt voor jullie meedenken tot zover.

Met vriendelijke groet,
Wilfred Dijksman

Reageren