[PHP] class &&singleton problemen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • g4wx3
  • Registratie: April 2007
  • Laatst online: 11-09 09:49
Hallo,
Ik heb de vakantie besteeds aan OOP.
Maar Ik kom er deze keer niet niet aan uit met php.

Enerzijds lukt het me langs geen kanten om een singleton te maken.
Anderzijds lukt het me niet om vanuit één klasse een andere klasse aan te roepen.

Ik zal er wat -niet werkende- code bijhalen

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
class config
    {
    static $file_handler_ini;
    
    function __construct()
    {
        $this->file_handle_ini = new file_handle('config.ini', true);   
    }
    
    function get_config()
    {
        return  $file_handler_ini->ini->set_config($config_new);
    }
    
    function set_config()
    {
        return $file_handler_ini->ini->get_config();
    }

$config_new =array  (
            'db_serveradress'=>'localhost:8889',
            'db_username'=>'ODCB',
            'db_password'=>'pppp'
                    );
config::set_config($config_new);
$settings = config::get_config();



Dit moet een singleton voorstellen, en onderaan zie e hoe dat ik het wil gebruiken.
De singleton moet het 'config.ini' bestand inlezen/bewerken.

Deze functies zitten in de klasse file_handle->ini->
bijvoorbeeld file_handle->ini->get_config()

Het zal voor de gevorderden hier een makkelijke vraag zijn, maar ik kom echt niet verder.
Ook liefst wat uitleg bij de singleton, want ik snap niet dat dat zo ingewikkeld moet zijn.
De singleton ken ik van javascript, en gebruik ik veel in JS.

http://www.softfocus.be/


Acties:
  • 0 Henk 'm!

Verwijderd

Singleton's doe ik meestal zo:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Config
{
    static private $_instance = null;
    
    private function _construct() { }
    
    public static function &getInstance() {
        if (null === self::$_instance) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }
}

Het idee is dat je de singleton aanroept met config::getInstance() en dat die functie dan de instance van zichzelf teruggeeft. De constructor is private, zodat je de class niet op een andere manier dan met getInstance kan aanroepen ;)

Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Verwijderd schreef op zaterdag 05 april 2008 @ 19:30:
Singleton's doe ik meestal zo:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Config
{
    static private $_instance = null;
    
    private function _construct() { }
    
    public static function &getInstance() {
        if (null === self::$_instance) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }
}

Het idee is dat je de singleton aanroept met config::getInstance() en dat die functie dan de instance van zichzelf teruggeeft. De constructor is private, zodat je de class niet op een andere manier dan met getInstance kan aanroepen ;)
Mag ik vragen waraom je in PHP 5 nog de & gebruikt ?

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

SchizoDuckie schreef op zaterdag 05 april 2008 @ 19:37:
[...]


Mag ik vragen waraom je in PHP 5 nog de & gebruikt ?
Het is een referentie naar een object, dus &, het moet niet, maar het mag :)

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • g4wx3
  • Registratie: April 2007
  • Laatst online: 11-09 09:49
Wauw, de korte bondige uitleg en ik begrijp het helemaal!
super bedankt daarvoor!

ik ga eens op onderzoek om te zien of de rest me nu ook lukt

http://www.softfocus.be/


Acties:
  • 0 Henk 'm!

  • WouZz
  • Registratie: Mei 2000
  • Niet online

WouZz

Elvis is alive!

Ik zal er wat -niet werkende- code bijhalen
Ik vind het wel grappig dat je in je set een get doet en in je get een set. Heb je daar doelbewust voor gekozen?

On track


Acties:
  • 0 Henk 'm!

  • g4wx3
  • Registratie: April 2007
  • Laatst online: 11-09 09:49
HIHI, foutje
Eerst stonden daar eigenlijk wat meer regeltjes (foreach ...).
Ik heb die functies overgezet naar de andere classe, en de alleen de essentie laten staan in de singleton.

http://www.softfocus.be/


Acties:
  • 0 Henk 'm!

  • g4wx3
  • Registratie: April 2007
  • Laatst online: 11-09 09:49
Ik heb het werkende. Bedankt, heb trouwens veel bijgeleerd met dit kleine voorbeeldje.

Maar ondertussen vraag ik me af waarom ik het zo moeilijk wilde maken.
Ik werk alleen al mag je zo eigenlijk niet denken, weet ik.

Om het voorbeeld erbij te halen:
ik had een classe geschreven om quick en dirty ini file te bewerken.
Veel tekortkomen aan de methodes, maar geschikt voor mijn doel.
Ik wilde niet teveel tijd besteden aan iets dat toch niet zo vaak moet gebruikt worden, geen nut dat ik het over complex maak.

De classe is niet geschikt om php.ini of zo aan te passen.
Ook wilde ik voorkomen dat het config.ini op meerdere keren werd geopend, wat onoverkomelijk leidt tot een corrupt bestand. (en dan is de boel stuk)
Nog belangrijker is dat iedereen dezelfde naam hanteert voor het config bestand.

Ik weet dat nu wel voor mij eigen. Door een singleton kan ik iedereen beperken.
Als iemand anders zou proberen een object te maken van die klasse krijgt die een foutmelding.

Maar ik kan dus evengoed een comment erbij zetten.
En omdat ik alleen werk weet ik waar die functie voor dient.

Waarom zoude julie een singleton gebruiken?

http://www.softfocus.be/


Acties:
  • 0 Henk 'm!

Verwijderd

g4wx3 schreef op zondag 06 april 2008 @ 16:56:
Ik heb het werkende. Bedankt, heb trouwens veel bijgeleerd met dit kleine voorbeeldje.

Maar ondertussen vraag ik me af waarom ik het zo moeilijk wilde maken.
Ik werk alleen al mag je zo eigenlijk niet denken, weet ik.

Om het voorbeeld erbij te halen:
ik had een classe geschreven om quick en dirty ini file te bewerken.
Veel tekortkomen aan de methodes, maar geschikt voor mijn doel.
Ik wilde niet teveel tijd besteden aan iets dat toch niet zo vaak moet gebruikt worden, geen nut dat ik het over complex maak.

De classe is niet geschikt om php.ini of zo aan te passen.
Ook wilde ik voorkomen dat het config.ini op meerdere keren werd geopend, wat onoverkomelijk leidt tot een corrupt bestand. (en dan is de boel stuk)
Nog belangrijker is dat iedereen dezelfde naam hanteert voor het config bestand.

Ik weet dat nu wel voor mij eigen. Door een singleton kan ik iedereen beperken.
Als iemand anders zou proberen een object te maken van die klasse krijgt die een foutmelding.

Maar ik kan dus evengoed een comment erbij zetten.
En omdat ik alleen werk weet ik waar die functie voor dient.

Waarom zoude julie een singleton gebruiken?
Singleton gebruik ik eigenlijk alleen voor het registry, een manier om het steeds gebruiken van Global te voorkomen.
Verder gooi ik andere classes zoals bijvoorbeeld database gewoon in het registry, zodat daar eigenlijk ook nooit meer dan 1 instance van bestaat :)

Acties:
  • 0 Henk 'm!

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 07-09 11:44

Bergen

Spellingscontroleur

Snake schreef op zaterdag 05 april 2008 @ 19:42:
[...]

Het is een referentie naar een object, dus &, het moet niet, maar het mag :)
Het mag wel ja, maar PHP 5 gebruikt automatisch references, dus het voegt niets meer toe.

Acties:
  • 0 Henk 'm!

  • Hielko
  • Registratie: Januari 2000
  • Laatst online: 20:07
Verwijderd schreef op zaterdag 05 april 2008 @ 19:30:
Singleton's doe ik meestal zo:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Config
{
    static private $_instance = null;
    
    private function _construct() { }
    
    public static function &getInstance() {
        if (null === self::$_instance) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }
}

Het idee is dat je de singleton aanroept met config::getInstance() en dat die functie dan de instance van zichzelf teruggeeft. De constructor is private, zodat je de class niet op een andere manier dan met getInstance kan aanroepen ;)
Ik ben (gelukkig :p ) geen php-programmeur, maar kan je nu niet nog steeds je object clonen waardoor je toch twee instanties van je singleton kan kriigen?

Acties:
  • 0 Henk 'm!

  • borft
  • Registratie: Januari 2002
  • Laatst online: 15-09 16:33
dat zou je kunnen afvangen door de __clone functie te definieren die dan niets doet, of een reference naar zichzelf teruggeeft...

Acties:
  • 0 Henk 'm!

  • Hielko
  • Registratie: Januari 2000
  • Laatst online: 20:07
Een exception lijkt me in zo'n geval op zijn plaats.

Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
borft schreef op zondag 06 april 2008 @ 18:35:
dat zou je kunnen afvangen door de __clone functie te definieren die dan niets doet, of een reference naar zichzelf teruggeeft...
De standaard oplossing is __clone private maken :) wat jij voorstelt gaat niet werken door de manier waarop __clone werkt.

[ Voor 11% gewijzigd door PrisonerOfPain op 06-04-2008 19:25 ]


Acties:
  • 0 Henk 'm!

Verwijderd

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
class Config{

    static private $_instance = NULL;
    
    private function _construct() { }
    
    //reference is overbodig!
    public static function getInstance() {
        //zo nog ietsje netter misschien ?
        if (self::$_instance !instanceof self) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    //blocked!
    private function __clone(){}
}
?>

[ Voor 3% gewijzigd door Verwijderd op 13-04-2008 08:15 ]


Acties:
  • 0 Henk 'm!

  • simon
  • Registratie: Maart 2002
  • Laatst online: 00:18
Je weet dat PHP5 alles by default als reference doorgeeft? Dit is een grote wijziging tov PHP4. Daarnaast ivnd ik je private _construct geval zo maar ranzig overkomen, dan concureer je met de __construct (die trouwens public moet zijn).

Maar ik heb altjid twijfels gehad bij singleton, helemaal als nu alles by reference door wordt gegeven, dan heeft 't toch geen zin? Of moet 't per sé in PHP4 werken?

[ Voor 4% gewijzigd door simon op 13-04-2008 08:21 ]

|>


Acties:
  • 0 Henk 'm!

Verwijderd

een private of protected __construct dat is nou eenmaal singleton. Het woord zegt het al 'single' er mag maar 1 instance gemaakt worden. Hetgeen soms wel handig is maar ook vaak verkeerd wordt toegepast.

Acties:
  • 0 Henk 'm!

  • simon
  • Registratie: Maart 2002
  • Laatst online: 00:18
mja maar in PHP5 bestaat er, zonder dat je 't object cloont dus alleen een reference naar het object, en dan blijft het een single instance..

Waarom zou je dan nog singleton gebruiken, dat zie ik even niet.

|>


Acties:
  • 0 Henk 'm!

  • Hielko
  • Registratie: Januari 2000
  • Laatst online: 20:07
Ik neem aan dat als je een object maakt in php, hij niet een reference naar een bestaand object geeft, maar gewoon dat object opnieuw aanmaakt:

bijv.

Object a = new Object();
Object b = new Object(); // is geen reference naar a

Bij een singleton zou dit niet kunnen, dan dwing je af dat iedereen altijd met hetzelfde object zit te werken. Er zijn verschillende gevallen te bedenken waarbij het niet logisch of wenselijk is dat een bepaald type object meerdere malen bestaat, wat bijv. als je een object hebt met de configuratie van je programma. Als er tegelijkertijd twee van deze objecten worden gemaakt, ze allebei worden aangepast: wat wordt dan het uiteindelijke resultaat?

Acties:
  • 0 Henk 'm!

  • RAJH
  • Registratie: Augustus 2001
  • Niet online
Als je bijvoorbeeld een registry zou gebruiken is het inderdaad niet nodig om een singleton te gebruiken, je krijgt dan namelijk altijd hetzelfde object terug uit je registry. Maar als je daar niet mee werkt en je bent op meerdere plekken in je code dezelfde instance nodig, dan lijkt me een singleton de enige oplossing. (Zonder gebruik te maken van een (super)global var).

Acties:
  • 0 Henk 'm!

Verwijderd

singleton voorkomt dat er meerdere instanties van de zelfde class gemaakt kunnen worden.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class database{
     public function __construct($host, $user, $password){
          //connect...
     }
     public function select($database){
         //select
     }
}

$dba = new database('localhost', 'blaat', 'schaap');
$dbb = new database('localhost', 'blaat', 'schaap');
?>


En voila je hebt 2 verbindingen met de database. Als je meerdere databases gebruikt kan dat zelfs een pre zijn natuurlijk.

PHP:
1
2
3
4
<?php
$dbc = clone $dba; 
$dbc->select('andere'); //zelfde verbinding andere database...
?>


En je hebt er 3 als het goed is... Weet ik eigenlijk niet helemaal in dit verband misschien moet je 'm dan nog iets met __clone(){} doen ?!

Dat gaat dus niet met singleton! reference of niet. Er wordt gewoon maar 1 instance aangemaakt.

Stond nog een foutje in mijn eerdere aanpassing zie ik:
PHP:
1
2
3
<?php
        if (!self::$_instance instanceof self) { //! verkeerd....
?>
Pagina: 1