is dit oop of niet?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: 1 2 volgende »

Tim S

Tim S

19/11/2012 22:00:10
Quote Anchor link
Ik ben sinds dit weekend begonnen met oop. Ik heb nu een klasse gemaakt actions hiermee kan ik bijvoorbeeld items verwijderen of update, ik vroeg me af op ik op de goede weg zit.

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
45
46
47
48
49
50
51
52
53
54
<?php
class actions{
    
    //query
    public $set_query;
    //resultaat mysql_query
    protected $execute_query;

    protected $result;
    //bericht succes
    public $set_message_true;
    //bericht mislukt
    public $set_message_false;
    //het aantal beinvloede rijen na het uitvoeren van de query
    public $set_affected_rows;
    
    
    //mysql_query uitvoeren
    public function execute_query(){
        
        $this->result = mysql_query($this->set_query);    
    }

    
    
    
    //check succes of niet
    public function check(){
        global $smarty;
                
        if($this->result && mysql_affected_rows() == $this->set_affected_rows){
            $smarty->assign('message',$this->set_message_true);
        }

        else{
            $smarty->assign('message',$this->set_message_false);
        }
    }
    
}


$delete = new actions();
                            
                            
$delete->set_query = "DELETE FROM content WHERE paginaid =$id";
$delete->set_message_true = 'succes';
$delete->set_message_false = 'mislukt';
$delete->set_affected_rows = 1;
                            
$delete->execute_query();
$delete->check();
                            
unset($delete);    


?>


Ik hoor graag op of aanmerkingen!!
Gewijzigd op 19/11/2012 22:01:00 door Tim S
 
PHP hulp

PHP hulp

28/03/2024 12:13:33
 
- Raoul -

- Raoul -

19/11/2012 22:28:13
Quote Anchor link
Nee. De gouden regel met OOP is: objecten, objecten, objecten!!
Vandaar ook de naam object oriënted programming.

Iedere class die je maakt mag maar één verantwoordelijkheid hebben. Ook moet dit een object zijn (= zelfstandig naamwoord).

Is 'actions' (=acties) een zelfstanding naamwoord (=object)? Nee. Dat is het niet. Ik raad je aan om een goede OOP beginnerstutorial te volgen op http://phptuts.nl.

Veel succes!
 
Ozzie PHP

Ozzie PHP

19/11/2012 22:37:22
Quote Anchor link
- Raoul - op 19/11/2012 22:28:13:
Iedere class die je maakt mag maar één verantwoordelijkheid hebben.

Raoul, wat versta je precies onder één "verantwoordelijkheid"?
 
Tim S

Tim S

19/11/2012 22:50:50
Quote Anchor link
Ik zoek nog een goede naam ipv actions.

De verantwoordelijkheid van deze class is volgens mij alleen een query uitvoeren en dan kijken of dit is gelukt.
Is het dan de bedoeling dat ik deze klass nog verder opsplits?
 
Ozzie PHP

Ozzie PHP

19/11/2012 22:55:47
Quote Anchor link
Tim... je moet meer in objecten denken. Bijv een 'user'. Je hebt dan een user class waarmee je user objecten kunt maken. Op zo'n user object kunt je weer functies uitvoeren.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
$user
= new User();
$user->setName('Tim Slootweg');
$user->save();
?>
 
Tim S

Tim S

19/11/2012 23:12:34
Quote Anchor link
Ik was bezig met een simpel cms systeem, daarvoor moet je update verwijderen en toevoegen. Daarom heb ik dit gemaakt. Het is de bedoeling dat ik dat ook voor andere dingen kan gebruiken, stel ik heb een gastenboek dan moet ik hier ook items verwijderen.
 
Ozzie PHP

Ozzie PHP

19/11/2012 23:16:36
Quote Anchor link
Maar dan moet je net even iets anders denken... er zijn er hier op het forum die hier nog veel beter in zijn, maar je moet dan ongeveer in deze richting denken. Zomaar een voorbeeldje...

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
$item_id
= $_GET['item_id'];
$item = new Item($item_id);
$item->delete();
?>
 
Reshad F

Reshad F

19/11/2012 23:23:24
Quote Anchor link
Tim je geeft zelf antwoord op je vraag

Quote:
De verantwoordelijkheid van deze class is volgens mij alleen een query uitvoeren en dan kijken of dit is gelukt.


Als er een 'EN' in je zin voor komt dan weet je dat je al meer dan 1 ding doet.

Verder zou ik beginnen met iets simpelers maken. Dit om de volgende redenen.

- Een class maken die alle acties voor jou makkelijk maakt omtrent queries is gewoon moeilijk om na te maken zelfs voor goede OOP programmeurs
- Wil je zoiets om echt te gebruiken alleen gebruik dan een ORM ( Object Relational Mapping ) een paar goede hiervan zijn Doctrine of Propel.

verder moet je in OO als het volgende denken

Elk object is een class. Deze class kan verschillende methoden hebben. bijvoorbeeld de User class die Ozzie als voorbeeld al gebruikt.
dit is een User ( persoon ) die verschillende dingen kan doen.

leven, lopen, eten, slapen, doodgaan. dit zijn dan de methoden van de User class. Je kan bijvoorbeeld in de User class geen methode meegeven die aangeeft welke ranking een User heeft. De oplossing hiervoor is bijvoorbeeld om de User class te extenden. zo krijg je dan bijvoorbeeld

Admin extends User waarbij Admin de User class overneemt en waarbij je nieuwe methoden kan meegeven die alleen de Admin class krijgt. Zo kan je verder weer een Employee class maken en noem maar op. Dit worden doorgaans Child classes genoemd. de User class is hierbij een Super class.

Ik zou de volgende tutorials doornemen om het een en ander goed te begrijpen:

http://www.phphulp.nl/php/tutorial/overig/het-princiepe-oop/302/
http://www.phphulp.nl/php/tutorial/overig/oop-beginnershandleiding-php5/701/

en deze is wel oud maar volgens mij nog wel goed

http://www.phphulp.nl/php/script/overig/database-class/478/

Ik denk dat dit wel genoeg leesvoer is voor nu :)
 
Tim S

Tim S

19/11/2012 23:23:48
Quote Anchor link
Ja kan, maar is het niet handiger om dat voor elke actie, delete, update etc. een class delete extends item te maken. Dan in de class item maak je een constructor met $item_id. Zou dit wel oop zijn??

Toevoeging op 19/11/2012 23:41:00:

@Reshad F
wat ik probeer te maken is inderdaad een db class, wat ik alleen niet begrijp is dat in de laatste link ook meerderen dingen gebeuren, dat database connectie wordt gemaakt daarna worden er ook query's uitgevoerd.

Is het dan wel oop als ik een db class heb met daarin een functie delete en hierin een bericht zet gelukt of mislukt??
 
Reshad F

Reshad F

20/11/2012 10:09:25
Quote Anchor link
Zoals ik al zei een (goede) Databaseclass is niet iets wat je zomaar even maakt. Zelfs voor een ervaren developer. zoals ik al zei is die laatste link behoorlijk oud al. dus het kan zijn dat het niet correct is meer. link is namelijk al 8 jaar oud. wil je zien hoe een goede DB class er echt uitziet dan zou ik de source van Doctrine bijvoorbeeld bestuderen.
 
Tim S

Tim S

20/11/2012 12:20:05
Quote Anchor link
Ja ik zal wat kleiner beginnen, ikmkan de class beter page noemen(wat wat nog vrij groot is)
Aleen bij een mens is het simpel een mens loopt praat etc. Maar een pagina update delete enzovoort. Aleen geeft een pagina een reactie nee, dus ik vraag me af of ik daar een andere class voor moet maken of dat je wel een bericht mag geven als de pagina succesvol is geupdate.

Ook had ik nu $delete->setquery =

Hiervoor kan ik beter doen function settable($table){
$this->table = $table;
}

En dan $page->settable('content');
 
Ozzie PHP

Ozzie PHP

20/11/2012 13:14:59
Quote Anchor link
Nee, je begrijpt het nog niet. Je moet niet een class page gaan maken om daarmee een pagina te updaten e.d.
Een class page zou je gebruiken om bijvoorbeeld een header, een footer, een content gedeelte en een pagina gedeelte in te stellen, maar niet zoals jij het in gedachten hebt.

Ga eerst wat basistutorials lezen, want ik merk dat je anders helemaal de verkeerde kant op gaat. En ik, en velen met mij, zijn fout begonnen. Daarom adviseer ik je echt om eerst het principe door te krijgen.

Een van onze forumleden, Wouter J, heeft ook een mooi artikel geschreven over het denken in objecten. Begin daar maar eens mee: http://wouterj.nl/php/eens-goed-nadenken-in-objecten/354/
 
Tim S

Tim S

20/11/2012 14:01:11
Quote Anchor link
Nee klopt ik zit even hardop te denken. Wat ik wel heb gemerkt is dat ik erg slecht ben in het bedenken van namen. Het basis idee van bijvoorbeeld een class pet met eigenschappen van een dier begrijp ik. Ik vindt het alleen moeilijk om het update delete in een class te zetten die daarvoor verantwoordelijk is. We gaan weer verder denken....
 
Ozzie PHP

Ozzie PHP

20/11/2012 14:04:36
Quote Anchor link
Je moet het denk ik ook niet zozeer zien als een aparte class, maar als onderdeel van een class.

Dus in jouw voorbeeldje met Pet:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
$pet
= new Pet();
$pet->setName('Rakker');
$pet->save();
?>


Volgens mij heb je dan ook weer een datamapper nodig, maar dat kan Wouter of iemand anders beter uitleggen dan ik.
Gewijzigd op 20/11/2012 14:05:09 door Ozzie PHP
 
Tim S

Tim S

20/11/2012 14:12:01
Quote Anchor link
Ja klopt volgens mij, maar daarom zat ik in het vorige voorbeeld te denken aan:


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
$page
= new Page();
$page->setName('home');
$page->save();
?>



Misschien is het idee nu iets duidelijker??
Alleen stel dat dit juist is dan zit je nog met delete en update kan dit dan ook in dezelfde class?
 
Reshad F

Reshad F

20/11/2012 16:37:13
Quote Anchor link
Nee nu denk je nog steeds fout. ik zou het zo doen. Maak een Page class en een PageStorage class. waar ik hiermee op doel is dat je nu een klasse hebt voor het aanmaken updaten deleten en lezen van de pagina een zogeheten CRUD class en een class die het opslaat.

wat je dan krijgt is bijvoorbeeld

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php

$page
= new Page();  // je maakt het object page aan.
$page->setName('home'); // geeft attributen mee
$page->setId('1234');

// slaat de page op dmv de storage class
$storage = new PageStorage();
$storage->save($page);

?>


nog mooier zou zijn om een interface te maken voor de CRUD methodes. bijvoorbeeld een interface genaamd StorageInterface deze kan door elke klas dan geimplementeerd worden.
Gewijzigd op 20/11/2012 16:39:41 door Reshad F
 
Wouter J

Wouter J

20/11/2012 16:49:51
Quote Anchor link
Ook jij begrijpt het niet helemaal, Reshad. Storage klassen, in de vorm die jij hier bedoelt, zijn de 'DB' klassen. Wat jij hier wilt hebben is een DataMapper.

Tevens kan de manier van Tim ook, je zit dan meer te denken aan een Active Record pattern.
 
Tim S

Tim S

20/11/2012 16:50:48
Quote Anchor link
Ja dit zit er helder uit, ik kan dan bijvoorbeeld een nog een class pagedelete maken. En een interface ga ik nog even kijken dan krijg je bijvoorbeeld class pagestorage implements interface.


Toevoeging op 20/11/2012 16:51:31:

Wast iets te snel, hoe zou jij het doen wouter?
 
Reshad F

Reshad F

20/11/2012 17:09:05
Quote Anchor link
Eh ja ging even fout in de benamingen maar wat wouterJ dus zegt, een DataMapper ( Zoals in mijn eerdere posts al gezegd een ORM dus )

de interface zou ik natuurlijk geen interface noemen. je krijgt dan iets van

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php

class PageStorage implements StorageInterface {
// doe je ding hier
}

?>


Het verschil tussen een DataMapper en een Active Record pattern is dat je bij een DataMapper door een externe class je queries afhandelt. bij een Active Record pattern zorgt deze zelf voor zijn CRUD methodes. Voor simpele dingen zou ik zeker voor een Active Record Pattern gaan maar wil je echt iets heel uitgebreids creëren dan zou ik toch kijken naar een DataMapper. De betere ORM's gebruiken deze manier ook. (@wouterJ correct me if im wrong :) ben ook nog niet zo lang bezig met OOP ;) dus kan ik gelijk zien of ik het goed heb begrepen )

Toevoeging op 20/11/2012 17:18:41:

edit: misschien handig om te lezen over Active Record Patterns

http://buggy.zoombug.com.au/wp-content/uploads/2007/03/activerecord.pdf
 
Erwin H

Erwin H

20/11/2012 17:37:42
Quote Anchor link
Active Record, DataMapper, ORM, etc etc.
Allemaal leuke termen, maar dat gaat compleet voorbij aan het feit dat de TS daar zo te zien nog niet aan toe is.

Even terug naar de basis; waarom OOP gebruiken. Als het alleen is omdat het leuk klinkt.... niet doen.
Het idee van OOP is dat je applicaties opbreekt in simpele, functionele componenten die eenvoudig, zonder aanpassing, zijn te hergebruiken. Ook in andere applicaties. Dit scheelt ontwikkel tijd, scheelt test tijd en maakt je applicatie robuster en beter onderhoudbaar.

Om dat voor elkaar te krijgen is echter wel enig denkwerk nodig. Met je eerste twee zinnen geef je al dat niet voldoende te hebben gedaan:
Tim Slootweg op 19/11/2012 22:00:10:
Ik ben sinds dit weekend begonnen met oop. Ik heb nu een klasse gemaakt

Met OOP is het van belang dat je eerst een structuur ontwerpt waarbinnen je alle verschillende componenten kunt onderscheiden en daarvoor kun je classes ontwerpen en bouwen. Dat doe je niet in een weekend, zeker niet als je net begint.

Begin je die klasses dan te bouwen, dan zijn ook daar een paar heel belangrijke zaken om aan te denken. Zonder compleet te willen zijn staat er 1 voorop:
- zorg dat je elke verandering altijd maar op 1 plek hoeft door te voeren.
Dit is overigens ook de reden dat elke klasse altijd maar 1 functionaliteit (verantwoordelijkheid) zou moeten hebben. Heeft een klasse er meer, dan kom je al gauw in de situatie dat je dezelfde code in een andere klasse zal zien opduiken.

In jouw geval blijkt bovenstaande ook nog niet goed doorgewerkt te zijn. Neem als voorbeeld het property $set_affected_rows. Aangezien het nu een public property is kan elke andere klasse die zo aanroepen en er iets in zetten. Dat kan een goed waarde zijn, maar kan ook een negatief getal zijn, een letter of een ander object. Op zeker moment zal je zien dat dat een keer fout gaat en zal je er dus een test aan willen toevoegen, om ervoor te zorgen dat de waarde ook bruikbaar is. Dat doe je dan via een setter, alleen al die andere klasses die nu al het public property gebruiken moet je dan ook aanpassen. Niet doen dus, NOOIT public properties gebruiken, altijd via een setter laten lopen, desnoods via een magic method. Wil je dan eens zo'n test tovoegen is er niets aan de hand.

Een ander probleem wat je krijgt is als je ooit eens deze klasse wil gaan gebruiken in een gezamenlijk project met een ander. Jij gaat dan de database kant doen (het model in MVC termen) terwijl die ander de output kant gaat doen (view in MVC termen). Is de applicatie goed opgebouwd en zijn de componenten goed opgebouwd, dan zou dat los van elkaar moeten kunnen gebeuren. Het model heeft geen weet van de view en andersom. Alleen..... in jouw geval gaat dat al mis. Je gebruikt namelijk een global $smarty in je database klasse. Dat is dus echt een hele grote NO-NO. NOOIT globals gebruiken in OOP. Hiermee bepaal je namelijk al dat de view gebruik moet gaan maken van smarty en veeg je in 1 keer een hele berg goeds van het gebruik van OOP van tafel.

Dus, eerst nog eens even terug naar de tekentafel. Ga je applicatie structuur uitdenken, bepaal welke componenten er nodig zijn, welke functionaliteiten nodig zijn en ontwerp aan de hand daarvan je klasses.
 
Wouter J

Wouter J

20/11/2012 17:51:15
Quote Anchor link
Tim, voor het afhandelen tussen een db en een klasse heb je erg veel methoden (design patterns genoemd):

Active Record Pattern
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<?php
class User
{
    private $id;
    private $name;
    private static $db;

    public function __construct($name)
    {

        $this->name = $name;
    }


    public static function setDatabase(PDO $db)
    {

        self::$db = $db;
    }


    public function setId($id)
    {

        $this->id = (int) $id;
    }


    public static function getDatabase()
    {

        return self::$db;
    }


    public function getId()
    {

        return $this->id;
    }


    public function getName()
    {

        return $this->name;
    }


    public function save()
    {

        if (null === $this->getId()) {
            // user moet aangemaakt worden
            $query = "INSERT users(name) VALUES ('".$this->getName()."');";

            // voer de query uit
            $db = self::getDatabase();
            $db->query($query);

            // stel het id in
            $this->setId($db::lastInsertId());
        }
else {
            // update de user in de tabel
            $query = "UPDATE users SET name = '".$this->getName()."' WHERE id = ".$this->getId().';';

            // voer de query uit
            self::getDatabase()->query($query);
        }
    }


    /**
     * Gets an User by his ID.
     *
     * @param int $id
     */

    public static function getById($id)
    {

        $query = "SELECT name FROM users WHERE id = ".(int) $id.';';

        // voer de query uit
        $result = self::getDatabase()->query($query);

        $result = $result->fetch(PDO:FETCH_ASSOC);

        // maak een nieuw user object aan
        $user = new static($result['name']);
        $user->setId($result['id']);
        $user::setDatabase(self::getDatabase());

        return $user;
    }
}


/************************\
       HET GEBRUIK
\************************/

$user = new User('Wouter');
$user->save(); // maak een nieuwe user aan in de db

$user = User::getById(2); // krijg de user bij id = 2
$user->setName('foo'); // verander de naam
$user->save(); // update de user in de db
?>


DataMapper Pattern
Hierdoor verplaats je alles wat te maken heeft met de db in een nieuwe klasse, dit wordt over het algemeen meer 'OO' gezien dan Active Record. Een uitleg + voorbeeld hiervan: http://www.phphulp.nl/php/forum/topic/oop-gedachtengang/85017/1/#606620

Een ORM
Object Relation Mapper, deze zorgt ervoor dat de db up to date blijft met het object:
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
<?php
$doctrine
= ...;
$em = $doctrine->getManager();

$user = new User('Wouter');
$em->persists($user); // voeg de user toe aan de lijst die Doctrine bij houdt
$em->flush(); // hou alles up to date

$user->setName('foo'); // verander iets
$em->flush(); // maak elk object weer up to date

$repo = $doctrine->getRepository('User');
$user = $repo->find(2); // krijg het object bij id = 2

$user->setName('foo'); // verander weer wat
$em->flush(); // en maak alles weer up to date
?>
 

Pagina: 1 2 volgende »



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.