Undefind Variables met CodeIgniter
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:
Quote:
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
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:
Quote:
Code (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
38
39
40
41
42
43
44
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
38
39
40
41
42
43
44
<?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;
}
}[/quote]
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;
}
}[/quote]
return $this->numberOfRows
Ik heb de functie getNumberOfRows() aangepast, maar de error blijft te voorschijn komen.
Heb nu de volgende code:
Quote:
Code (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
38
39
40
41
42
43
44
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
38
39
40
41
42
43
44
<?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;
}
}
[/quote]
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;
}
}
[/quote]
$this->numberOfRows; <-- moet het zijn, dus de 2e $ weg..
Dus bij een $this verwijzing hoofd er geen $ teken meer achter de daadwerkelijk variable meer.
Juist :)
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.
Als je classes extend gebeuren er ogenschijnlijk onnatuurlijke dingen:
Code (php)
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:
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.
Gewijzigd op 27/07/2015 21:51:45 door Thomas van den Heuvel
Hoe zou ik dan classes kunnen combineren zonder dat de uitbreidbaarheid minder word of weg gaat?
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.
Thomas van den Heuvel op 27/07/2015 21:48:16:
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.
Als je de base class in getters en setters voorziet is de uitbreiding totaal niet lastig:
($p staat voor property)
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
class A
{
private $p;
public function setP($p)
{
$this->p = strtolower($p);
}
}
class B extends A
{
function __construct($p)
{
$this->setP($p);
}
}
?>
class A
{
private $p;
public function setP($p)
{
$this->p = strtolower($p);
}
}
class B extends A
{
function __construct($p)
{
$this->setP($p);
}
}
?>
Het voordeel hiervan is dat $p van class A in dit voorbeeld ook in de extended class altijd lowercase zal zijn.
Toevoeging op 28/07/2015 01:16:21:
Ben het overigens ook met Rickert eens maar ik vind wel dat je gerust Codeigniter kunt gebruiken als springplank naar Symfony omdat Symfony echt een behoorlijke leercurve heeft.
Gewijzigd op 28/07/2015 01:14:36 door Frank Nietbelangrijk
Verder gebruik ik CodeIgniter omdat dit redelijk simpel te gebruiken is en te snappen. Andere frameworks zijn/lijken ingewikkeld. Maar zo te horen is het de moeite om andere frameworks te proberen...
Thnx voor de reacties ik ga ermee aan de gang.
Pak Symfony2 en als je start vragen hebt, maak een topic aan en we/ik help je.
Zelf kom ik van Codeigniter en ik raadt je Symfony2 echt aan, het werkt net ff anders maar is veel beter voor je toekomst.
Frank Nietbelangrijk op 28/07/2015 01:06:39:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
class A
{
private $p;
public function setP($p)
{
$this->p = strtolower($p);
}
}
?>
class A
{
private $p;
public function setP($p)
{
$this->p = strtolower($p);
}
}
?>
Kijk eens wat je daar effectief doet. Je hebt een private var die publiekelijk instelbaar (en wss dan ook opvraagbaar - je hebt het over setters en getters -) is. Hoe is dat anders dan public $p? Dit lijkt mij een verkapte manier om een private variabele altijd toegankelijk te maken.
De protected aanduiding in mijn voorbeeld is (veel) transparant(er): daaruit is impliciet duidelijk waar een variabele toegankelijk is: in die klasses en afgeleide klasses.
Waarom niet meteen alles public maken in jouw geval? Scheelt je een hoop getters en setters.
Als je dan toch van zo'n constructie gebruik wilt maken, gebruik dan de magic methods __get() en __set(), dan ben je in 1x klaar.
En het gaat mij niet om al dan geen (magic) getters/setters. Helemaal mee eens dat je dat niet in alle gevallen nodig hebt. Waar het mij met name om ging is om aan te tonen hoe een base class ten aller tijde een property kan formatten in bijvoorbeeld lowercase letters. Je hoeft niet meer bang te zijn dat dit niet gebeurt als de class uitgebreid wordt.