Beste Allen,

Na een tijd van quick and dirty programmeren in PHP ben ik begonnen met het gebruik van een Framework. Ik heb gekozen voor CodeIgniter. Echter loop ik nu tegen een probleem aan waar ik niet aan uit kan komen. Ik pass variabelen van mijn model door tot aan de view, echter geeft hij in het model al aan dat een bepaalde variable undefined is maar hij lijkt mij goed gedefineerd.

Overigens geeft de gebruikte SPARQL query output.

De error:

A PHP Error was encountered

Severity: Notice

Message: Undefined variable: numberOfRows

Filename: models/dataset_model.php

Line Number: 42

Backtrace:

File: C:\wamp\www\SPARQL_project\application\models\dataset_model.php
Line: 42
Function: _error_handler

File: C:\wamp\www\SPARQL_project\application\controllers\dataset.php
Line: 15
Function: getNumberOfRows

File: C:\wamp\www\SPARQL_project\index.php
Line: 292
Function: require_once


De code:

Model:
<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class dataset_model extends CI_Model{

private $numberOfRows;
private $result;

function __construct()
{
parent::__construct();
$numberOfRows = 0;
$result = array();
}

function get_dataset()
{
require_once("application\libraries\sparqllib.php");
$db = sparql_connect("http://lod.geodan.nl/sparql/");
if( !$db ) { print sparql_errno() . ": " . sparql_error(). "\n"; exit; }
sparql_ns( "bag","http://lod.geodan.nl/vocab/bag#" );

$sparql = "select ?naam count(distinct ?openbareruimtemutatie) as ?aantal
where {
?openbareruimtemutatie a bag:Openbareruimtemutatie .
?openbareruimtemutatie bag:lastKnown \"true\"^^xsd:boolean .
?openbareruimtemutatie bag:openbareruimtenaam ?naam
}
group by ?naam
order by desc(?aantal)";
$result = sparql_query($sparql);
$this->setNumberOfRows($result);
if( !$result ) { print sparql_errno() . ": " . sparql_error(). "\n"; exit; }else{
return $result;}
}

function setNumberOfRows($result){
$this->$numberOfRows = sparql_num_rows($result);
}

function getNumberOfRows(){
return $numberOfRows;
}
}
return $this->numberOfRows
Dank voor je reactie wes.
Ik heb de functie getNumberOfRows() aangepast, maar de error blijft te voorschijn komen.
Heb nu de volgende code:


<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class dataset_model extends CI_Model{

private $numberOfRows;

function __construct()
{
parent::__construct();
$numberOfRows = 0;
$result = array();
}

function get_dataset()
{
require_once("application\libraries\sparqllib.php");
$db = sparql_connect("http://lod.geodan.nl/sparql/");
if( !$db ) { print sparql_errno() . ": " . sparql_error(). "\n"; exit; }
sparql_ns( "bag","http://lod.geodan.nl/vocab/bag#" );

$sparql = "select ?naam count(distinct ?openbareruimtemutatie) as ?aantal
where {
?openbareruimtemutatie a bag:Openbareruimtemutatie .
?openbareruimtemutatie bag:lastKnown \"true\"^^xsd:boolean .
?openbareruimtemutatie bag:openbareruimtenaam ?naam
}
group by ?naam
order by desc(?aantal)";
$result = sparql_query($sparql);
$this->setNumberOfRows($result);
if( !$result ) { print sparql_errno() . ": " . sparql_error(). "\n"; exit; }else{
return $result;}
}

function setNumberOfRows($result){
$this->$numberOfRows = sparql_num_rows($result);
}

function getNumberOfRows(){
return $this->$numberOfRows;
}
}
$this->numberOfRows; <-- moet het zijn, dus de 2e $ weg..
Ah,.. stom stom stom.. Helemaal over het hoofd gezien. Dank u!
Dus bij een $this verwijzing hoofd er geen $ teken meer achter de daadwerkelijk variable meer.
Nog een speciale reden dat je private gebruikt i.p.v. protected?
@Thomas van den Heuvel: even een vraagje, waarom zou dat uitmaken? Want zelf denk ik hier ook over na omdat ik met OOP aan het oefenen ben.
Uitbreidbaarheid / herbruikbaarheid.

Als je classes extend gebeuren er ogenschijnlijk onnatuurlijke dingen:
<?php
class A {
    private $test;

    public function __construct() {
        $this->test = 'hello';
    }


    public function getTest() {
        return $this->test;
    }
}

class B extends A {
    public function __construct() {
        $this->test = 'wat';
    }
}

$b = new B;
echo $b->getTest();
?>

Je zou misschien verwachten dat er "wat" wordt afgedrukt, maar er wordt niets afgedrukt (of liever gezegd NULL).

Bekijk de var_dump van $b maar eens:
object(B)#1 (2) {
  ["test":"A":private]=>
  NULL
  ["test"]=>
  string(3) "wat"
}

De private var $test van A is niet beschikbaar in B, wat je dus effectief doet in de aangepaste __construct in B is on-the-fly een nieuwe (publieke) variabele $test maken.

Ook als je parent::__construct() toevoegt in de __construct van B dan drukt $b->getTest() (nog steeds) "hello" af.

Als je $test in A protected maakt is deze wel beschikbaar in B, en werkt de code naar mijn mening ook wat logischer (er wordt "wat" afgedrukt).

Op het moment dat je "private" in een class gebruikt wordt het extenden van zo'n class vrij lastig. Je zou kunnen stellen dat dit tegenstrijdig is met de basisprincipes van OOP die juist bedoeld is om code zo te schrijven dat deze herbruikbaar is.
Hoe zou ik dan classes kunnen combineren zonder dat de uitbreidbaarheid minder word of weg gaat?
Nick, please kijk of je een ander Framework kan pakken.
Kijk naar Symfony2

Ik ben 2 jaar bezig geweest met Codeigniter en het is niet echt super goed OOP. Je leert er wel wat van maar het is beter om een ander framework te pakken.

Mocht je hier helaas bij blijven kijk dan sowieso naar de Active Record class van Codeigniter.

Reageren