OOP database class

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: 1 2 volgende »

Joakim Broden

Joakim Broden

24/08/2011 20:29:27
Quote Anchor link
Ik heb het onderstaande in elkaar geknutseld met OOP, is dit een beetje goed of helemaal fout?

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<?php
        class Database {
            // @param String
            private $db;
            // @param String
            private $query;

            /**
             * Constructor, connect to the database
             * @param String $host, The host to connect
             * @param String $database, The database to connect
             * @param String $user, The database user
             * @param String $password, The database password
             */

            public function __construct($host = 'localhost', $database, $user, $password) {
                if($host && $database && $user && $password) {
                    if (mysql_connect($host, $user, $password)) {
                        if (!$this->db = mysql_select_db($database)) {
                            throw new SQLException('Connection with the database failed.');
                        }
                    }
else{
                        throw new SQLException('Connection with the server failed.');
                    }
                }
else{
                    throw new SQLException('1 or more database parameters are missing.');
                }                
            }

            
            /**
             * Check if there is a database connection
             * @return Boolean
             */

            private function isConnected() {
                if ($this->db == '') {
                    throw new SQLException('There is no database connection.');
                    
                    return false;
                }
            }

            
            /**
             * Set a query
             * @param String $query, The preforming query
             * @return Resource, The preformed query
             */

            public function setQuery($query) {
                $this->isConnected();
                
                if ($query) {
                    if ($this->query = mysql_query($query)) {
                        return $this->query;
                    }
else{
                        throw new SQLException('Query failed, reason: '.mysql_error());
                    }
                }
else{
                    throw new SQLException('1 or more query parameters are missing.');
                }
            }

            
            /**
             * Get the num rows from last preformed query
             * @param String $query, The preformed query
             * @return Integer
             */

            public function getNumRows($query = '') {
                $this->isConnected();
                
                if (is_resource($query) || is_resource($this->query)) {
                    $query = (!is_resource($query)) ? $this->query : $query;

                    if ($numRows = mysql_num_rows($query)) {
                        return $numRows;
                    }
else{
                        throw new SQLException('Query failed, reason: '.mysql_error());
                    }
                }
else{
                    throw new SQLException('No query preformed.');
                }
            }


            /**
             * Get the fetch from last preformed query
             * @param String $query, The preformed query
             * @return Array
             */

            public function getFetch($query = '') {
                $this->isConnected();
                
                if (is_resource($query) || is_resource($this->query)) {
                    $query = (!is_resource($query)) ? $this->query : $query;
                    
                    if ($fetch = mysql_fetch_array($query)) {
                        return $fetch;
                    }
else{
                        throw new SQLException('Query failed, reason: '.mysql_error());
                    }
                }
else{
                    throw new SQLException('No query preformed.');
                }
            }


            /**
             * Get the last inserted id
             * @return Integer
             */

            public function getLastId() {
                $this->isConnected();
                
                return mysql_insert_id();
            }
        }


    try {
        $db = new Database(HOST, DATABASE, USER, PASSWORD);
        
        $result = $db->setQuery('SELECT id FROM table_test');
        $result = $db->getFetch($result);

        echo $db->getNumRows();
    }
catch (CoreException $error) {
        echo $error->getMessage();
    }
catch (SQLException $error) {
        echo $error->getMessage();
    }

?>
Gewijzigd op 25/08/2011 09:38:44 door Joakim Broden
 
PHP hulp

PHP hulp

28/07/2021 11:43:32
 
Fabian M

Fabian M

24/08/2011 20:32:39
Quote Anchor link
Gebruik block-comments;

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
/**
 * Constructs a new Database instance
 * @param String $root The host to connect to.
 * @param String $database The name of the database.
 * @param String $user
 * @param String $password
 */
 
Ozzie PHP

Ozzie PHP

24/08/2011 20:41:50
Quote Anchor link
Fabian M op 24/08/2011 20:32:39:
Gebruik block-comments;

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
/**
 * Constructs a new Database instance
 * @param String $root The host to connect to.
 * @param String $database The name of the database.
 * @param String $user
 * @param String $password
 */

Dat is natuurlijk geheel persoonlijk! Zoals Hertog Jan het doet kan het ook.
 
Fabian M

Fabian M

24/08/2011 20:46:46
Quote Anchor link
Ozzie PHP op 24/08/2011 20:41:50:
Fabian M op 24/08/2011 20:32:39:
Gebruik block-comments;

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
/**
 * Constructs a new Database instance
 * @param String $root The host to connect to.
 * @param String $database The name of the database.
 * @param String $user
 * @param String $password
 */

Dat is natuurlijk geheel persoonlijk! Zoals Hertog Jan het doet kan het ook.




Ik zou het alleen adviseren voor het uitleggen van een lijn, niet meerderen.
 
Jacco Brandt

Jacco Brandt

24/08/2011 21:13:14
Quote Anchor link
Waarom gooi je een coreException als een query niet werkt?
 
The Force

The Force

24/08/2011 21:17:50
Quote Anchor link
Het voordeel van die block comment is dat je er documentatie mee kan laten genereren. PHP Documentor accepteert geen //. Zie http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.quickstart.pkg.html .
 
Joakim Broden

Joakim Broden

24/08/2011 21:27:53
Quote Anchor link
Jacco Brandt op 24/08/2011 21:13:14:
Waarom gooi je een coreException als een query niet werkt?


Dit omdat ik op internet heb gelezen dat je met throw/try/catch een mooie fout afhandeling kunt maken, als een query niet werkt is dat toch een fout? Of kan dit beter?
 

24/08/2011 21:47:13
Quote Anchor link
Ik zou een nette afhandeling geven. Met een aangepast bericht die past bij je layout. Anders schrikt het zo af...
 
PHP Scripter

PHP Scripter

24/08/2011 21:59:25
Quote Anchor link
Ik zou helemaal gek worden van deze manier van programmeren. Ik vindt het er niet overzichtelijk uitzien. Maar iedere zijn eigen style.
 
Ozzie PHP

Ozzie PHP

24/08/2011 22:52:11
Quote Anchor link
Het is anders wel rete handig hoor... als je in het catch-blok verwijst naar een mooie 'foutmelding'-view dan kun je je foutmeldingen op een hele gelikte manier tonen, terwijl je op de plekken in de code waar zich een fout kan voordoen alleen maar 1 zinnetje tekst hoeft neer te zetten. Verder hoef je nergens aan te denken.
 
Jacco Brandt

Jacco Brandt

24/08/2011 23:05:10
Quote Anchor link
Maar het is geen CoreException, maar een SQL, of Database-Exeption.
 
Ozzie PHP

Ozzie PHP

24/08/2011 23:14:06
Quote Anchor link
Oh, oke... ik weet niet wat CoreException is. Is dat een eigengemaakte class of onderdeel van een framework?

Mijn reactie was meer bedoeld als reactie op PHP Scripter die die manier van programmeren onoverzichtelijk vind.

Wat ik zelf wel eens heb gedaan is alles in 1 try - catch blok zetten....

In de try start ik m'n framework op en als ie ergens (waar dan ook) een exception tegenkomt dan laat ik 'm een view aanroepen waarin de foutmelding wordt getoond.

Dit stukje, zoals de topicstarter doet:

try {
$db = new Database(HOST, DATABASE, USER, PASSWORD);

$result = $db->setQuery('SELECT id FROM table_test');
$result = $db->getFetch($result);

print_r($results);
} catch (CoreException $error) {
echo $error->getMessage();
}

... hoef ik niet te doen. Dat zou bij mij dan gewoon dit zijn:

$db = new Database(HOST, DATABASE, USER, PASSWORD);

$result = $db->setQuery('SELECT id FROM table_test');
$result = $db->getFetch($result);

print_r($results);

Dat gaat prima, omdat alles uiteindelijk in het try - catch blok staat.
 
- Ariën -
Beheerder

- Ariën -

24/08/2011 23:17:05
Quote Anchor link
Ja, maar het gaat om het voorbeeld, welke onder de class staat.
Op die manier werkt mijn CMS overigens ook. ;-)


Misschien een leuke toevoeging voor de class:
getTotalExecutedQueries(), uitleg lijkt me niet nodig ;-)

Misschien kan je ook een classe bouwen (lang leven OOP) die een meting doet hoelang een query draait. Leuk voor benchmarking en debugging.
Gewijzigd op 24/08/2011 23:19:30 door - Ariën -
 
Ozzie PHP

Ozzie PHP

24/08/2011 23:19:37
Quote Anchor link
- Aar - op 24/08/2011 23:17:05:
Ja, maar het gaat om het voorbeeld, welke onder de class staat.
Op die manier werkt mijn CMS overigens ook. ;-)


Misschien een leuke toevoeging voor de class:
getTotalExecutedQueries(), uitleg lijkt me niet nodig ;-)

De manier van de topicstarter, of zoals ik 'm beschreef?
 
- Ariën -
Beheerder

- Ariën -

25/08/2011 00:09:30
Quote Anchor link
tussen een algemeen try - catch blok.... ;-)
 
Ozzie PHP

Ozzie PHP

25/08/2011 00:31:59
Quote Anchor link
ah oke, nice :-)
 
Joakim Broden

Joakim Broden

25/08/2011 09:18:39
Quote Anchor link
@PHPscripter, wat vind jij er onoverzichtelijk aan. Hoe zou jij het doen dan?

@Ozzie en Aar, jullie raden dus aan om alles met throw new shizzle te doen en dan alle throws opvangen in 1 try/catch blok. Dus dan zou je dit krijgen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
try {
    // Hier komt dan de complete CMS/Website/Applicatie, met dus alle     classes/html/javasscript ed
} catch (CoreException $error) {
    // Hier de code tonen van de foutmelding
}
?>


Diverse vragen die mij nog oproepen:

1) Maar als je dan bijvoorbeeld een CoreException, SQLException hebt en dergelijke hoe vang je die dan op omdat je maar 1 catch hebt? Of moet je dan met meerdere catch werken zoals:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
try {
    // Hier komt dan de complete CMS/Website/Applicatie, met dus alle     classes/html/javasscript ed
} catch (CoreException $error) {
    // Hier de code tonen van de foutmelding 'Core'
} catch (SQLException $error) {
    // Hier de code tonen van de foutmelding 'SQL'
}
?>

2) Als je voor elk soort fout een aparte Exception maakt zoals CoreException, SQLException, krijg je op het laatst toch heel veel Exception classes? Zorgt dit niet voor te veel code en dergelijke?

In de begin post heb ik nu de nieuwe code geplaatst, maar zit ik een beetje op de goede weg of raden jullie mij anderdere dingen qua OOP/Throw. Graag tips en tricks :)
Gewijzigd op 25/08/2011 09:37:58 door Joakim Broden
 
Jelmer -

Jelmer -

25/08/2011 09:47:02
Quote Anchor link
Je database object heeft nu een state, de laatste aanroep naar setQuery bepaald hoe getResults werkt. Dat lijkt mij aardig verwarrend, ga maar eens na wat er in deze lap code gebeurt:
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
<?php

$db
= new Database(...);

function
list_topics()
{

    global $db;

    $db->setQuery("SELECT id, title, last_post_datetime FROM topics");

    while ($topic = $db->getFetch())
        echo $topic['title'] . " (" . user_format_timestamp($topic['last_post_datetime']) . ")\n";
}

function
user_format_timestamp($timestamp)
{

    $format = user_get_preference('timestamp_format', 'd-m-Y');
    return date($format, $timestamp);
}

function
user_get_preference($key, $default_value = null)
{

    static $preferences;

    if (!$preferences)
        $preferences = user_fetch_preferences($_SESSION['user_id']);

    return isset($preferences[$key])
        ?
$preferences[$key]
        :
$default_value;
}

function
user_fetch_preferences($user_id)
{

    global $db;

    $db->setQuery("SELECT key, value FROM preferences WHERE user_id = $user_id");

    $preferences = array();
    while ($row = $db->getFetch())
        $preferences[$row['key']] = $row['value'];

    return $preferences;
}


list_topics();
?>


Ik zou toch meer PDO's idee aanhouden, waarbij PDO::query een PDOStatement object teruggeeft, en je PDOStatement::fetch gebruikt om van die ene query de resultaten op te halen. Zo lopen je resultaten nooit door elkaar.
Gewijzigd op 25/08/2011 09:47:41 door Jelmer -
 
- Ariën -
Beheerder

- Ariën -

25/08/2011 09:48:47
Quote Anchor link
Maar PDO heeft toch ook weer een aparte exception. Dus als je twee soorten foutmeldingen wilt tonen, zit je toch met ingenestte try-catch blokken?
Gewijzigd op 25/08/2011 09:58:53 door - Ariën -
 
Ozzie PHP

Ozzie PHP

25/08/2011 10:12:30
Quote Anchor link
Hertog Jan op 25/08/2011 09:18:39:
@Ozzie en Aar, jullie raden dus aan om alles met throw new shizzle te doen en dan alle throws opvangen in 1 try/catch blok. Dus dan zou je dit krijgen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
try {
    // Hier komt dan de complete CMS/Website/Applicatie, met dus alle     classes/html/javasscript ed
} catch (CoreException $error) {
    // Hier de code tonen van de foutmelding
}
?>


Dat was wel hoe ik het destijds gedaan had, maar dan deed ik het ongeveer op deze manier:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
try {
    // Hier komt dan de complete CMS/Website/Applicatie, met dus alle     classes/html/javasscript ed
} catch (Exception $error) {
    // Eigengemaakte class aanroepen.
        MyException::show();
}

?>


Op het moment dat je ergens een exception throwde dan kon ik er een extra 'type' parameter aan mee geven:

throw new MyException('Geen database verbinding' , 'database');

In MyException vang je dan het type op (de default zet je dan bijvoorbeeld op 'standard'). Op het moment dat het type 'database' is (zoals hierboven) kun je daar de layout van je view op aanpassen door bijvoorbeeld een plaatje van een database te tonen, of door een aparte titel boven de foutmelding te zetten 'Database fout:'.

In plaats van dat je dus allerlei verschillende soorten exceptions heb, gebruik je er slechts 1 (MyException) en daar stuur je alles naartoe. Aan de hand van de parameter wordt in de MyException class bepaald om wat voor soort Exception het gaat.

Geen idee of dit een goede manier is, maar ik vind het wel handig.
Gewijzigd op 25/08/2011 10:15:26 door Ozzie PHP
 

25/08/2011 10:26:20
Quote Anchor link
The Force op 24/08/2011 21:17:50:
Het voordeel van die block comment is dat je er documentatie mee kan laten genereren. PHP Documentor accepteert geen //. Zie http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.quickstart.pkg.html .


Heb ik nog mooit gezien. Lijkt me best handig...
 

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.