Undefind Variables met CodeIgniter

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

PHP Nick

PHP Nick

27/07/2015 16:26:00
Quote Anchor link
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:
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


De code:

Model:
Quote:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?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]
 
PHP hulp

PHP hulp

25/12/2024 21:58:20
 
- wes  -

- wes -

27/07/2015 16:30:25
Quote Anchor link
return $this->numberOfRows
 
PHP Nick

PHP Nick

27/07/2015 17:10:36
Quote Anchor link
Dank voor je reactie wes.
Ik heb de functie getNumberOfRows() aangepast, maar de error blijft te voorschijn komen.
Heb nu de volgende code:

Quote:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?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]
 
Marthijn Buijs

Marthijn Buijs

27/07/2015 17:49:03
Quote Anchor link
$this->numberOfRows; <-- moet het zijn, dus de 2e $ weg..
 
PHP Nick

PHP Nick

27/07/2015 17:57:38
Quote Anchor link
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.
 
Marthijn Buijs

Marthijn Buijs

27/07/2015 19:30:03
Quote Anchor link
Juist :)
 
Thomas van den Heuvel

Thomas van den Heuvel

27/07/2015 21:16:00
Quote Anchor link
Nog een speciale reden dat je private gebruikt i.p.v. protected?
 
Marthijn Buijs

Marthijn Buijs

27/07/2015 21:20:04
Quote Anchor link
@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.
 
Thomas van den Heuvel

Thomas van den Heuvel

27/07/2015 21:48:16
Quote Anchor link
Uitbreidbaarheid / herbruikbaarheid.

Als je classes extend gebeuren er ogenschijnlijk onnatuurlijke dingen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
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.
Gewijzigd op 27/07/2015 21:51:45 door Thomas van den Heuvel
 
Marthijn Buijs

Marthijn Buijs

27/07/2015 22:08:12
Quote Anchor link
Hoe zou ik dan classes kunnen combineren zonder dat de uitbreidbaarheid minder word of weg gaat?
 

27/07/2015 22:19:09
Quote Anchor link
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.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

28/07/2015 01:06:39
Quote Anchor link
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)
PHP script in nieuw venster Selecteer het PHP script
1
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);
    }
}

?>


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
 
PHP Nick

PHP Nick

28/07/2015 10:38:24
Quote Anchor link
@Thomas, nee er is geen speciale reden waarom dat ik private i.p.v. protected gebruik. Ik gebruik private omdat ik gewend ben dit ook te doen bij bijvoorbeeld een JAVA applicatie waarbij ik over het algemeen Get en Set methodes gebruik om de variable te gebruiken.

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.
 

28/07/2015 11:56:12
Quote Anchor link
Hoi Nick,

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.
 
Thomas van den Heuvel

Thomas van den Heuvel

28/07/2015 13:50:57
Quote Anchor link
Frank Nietbelangrijk op 28/07/2015 01:06:39:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?php

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.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

28/07/2015 16:56:58
Quote Anchor link
Thomas, ik zal in sommige gevallen ook zeker een protected variabele toepassen maar zeker niet in alle gevallen. Het hangt mij inziens af van de toepassing waarvoor de property dient. Mijn vorige post was enkel een variant op de jouwe.
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.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.