WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   PHP getters i klasser, funkar det? (https://www.wn.se/forum/showthread.php?t=1054260)

Conny Westh 2012-07-23 01:51

PHP getters i klasser, funkar det?
 
Jag har testat lite php för skoj skull och nyfikenhet. Ville se hur implementationen av objektorrientering ser ut i PHP.

Hittils är jag inte ett dugg impad, de exempel på klasser, metoder och object på php.net lämnar mycket ett önska.

Hur som helst så testade jag hur det står till med getters och setters som finns i de flesta andra objektoerienterade programmeringsspråk.

Setters fick jag att funka även om det ser väldigt oelegangt löst ut enligt syntaxen, men det funkar i alla fall.

Men getters har jag inte lyckats få till. Hur tusan åstadkommer man det på ett bra sätt?

Bifogar min testkod som kompilerar felfritt som den ser ut med version 5.3.15.

Kod:

<?php
 class Person
 {
  private $_firsName="";
  private $_lastName="";

  public function __construct($pFirstName, $pLastName)
  {
    $this->_firstName = $pFirstName;
    $this->_lastName = $pLastName;
  }

        /* property setters */
        /*
        * The setters works as expected....
        */
        public function _set_firstName($value)
        {
                  $this->_firstName = $value;
        }
        public function _set_lastName($value)
        {
                  $this->_lastName = $value;
        }


        /* property getters */
        /*
        * The getters DON'T work as expected....
        * Get errorcode 255 with no further explanation.
        * Dont find any information about getters in documentation
        */
        /*
        * public string function _get_firstName()
        * {
          *        return $this->_firstName;
        * }
        * public string function _get_lastName()
        * {
          *        return $this->_lastName;
        * }

        */
  /*
    * a String representation for all Persons.
    */
        public function __toString()
        {
                return "Firstname: $this->_firstName , Lastname: $this->_lastName";
        }
}


?>

<?php
        # create a PHP Array and initialize it with Person objects
        $persons = array
        (
                new Person("Fredrik", "Hammarberg"),
                new Person("Greta", "Karlestam"),
                new Person("Urban", "Hallin"),
                new Person("Anna", "Bygdén")
        );

        # print out the results - calls Person->__toString().
        foreach($persons as $person) echo "$person<br>\n";
?>


Weaver 2012-07-23 02:42

Använd __get och __set
 
PHP har två så kallade magiska funktioner för att implementera getters och setters. De heter __get respektive __set och de tar emot värdets namn som argument.

Här är en snabb klass för att demonstrera det hela.
Kod:

class Person
{
    public function __set($name, $value)
    {
        switch ($name)
        {
            case 'firstname':
                $this->firstname = $value;
                break;
           
            case 'lastname':
                $this->lastname = $value;
                break;
        }
    }
   
    public function __get($name)
    {
        switch ($name)
        {
            case 'firstname':
                return $this->firstname;
           
            case 'lastname':
                return $this->lastname;
        }
       
        return null;
    }
   
    private $firstname;
    private $lastname;
}

Här är en alternativ implementation som istället använder en array för att lagra värdena:
Kod:

class Person
{
    public function __set($name, $value)
    {
        $this->name[$name] = $value;
    }
   
    public function __get($name)
    {
        if (isset($this->name[$name])) {
            return $this->name[$name];
        }
       
        return null;
    }

    private $name = array();
}

Och här kommer ett användningsfall:
Kod:

$person = new Person();
$person->firstname = 'Conny';
$person->lastname = 'Westh';

echo "{$person->firstname} {$person->lastname}";

Hoppas det hjälper dig!

HenrikAI 2012-07-23 10:03

public string function _get_firstName() => public function _get_firstName()

Conny Westh 2012-07-23 19:50

Nu har jag testat vidare och får ett nasty felkod på 255 som jag inte inser vad det är. Har ingen riktig IDE utan kör med Textpad som editor.

La till felhantering i get och set så man fångar upp felaktiga propertynamn.

Kod:

<?php
class Person
{
    private $firstname;
    private $lastname;

        public function __construct($pFirstname, $pLastname)
        {
                $this->firstname = $pFirstname;
                $this->lastname = $pLastname;
        }

    public function __set($name, $value)
    {
        switch ($name)
        {
            case 'firstname':
                $this->firstname = $value;
                break;

            case 'lastname':
                $this->lastname = $value;
                break;

            default:
                            # By throwing Exception for undefined property we can enforce strict property definition rules
                            # we also achive better error messages for improved debugging during development
                            # this is necessare because of lack of support for strict properties in php 5.3.15
                            $error = "Error: __set property: " . $name . " not supported by class: " . __CLASS__ ;
                                        throw new Exception($error);
                                        break;
        }
    }

    public function __get($name)
    {
        switch ($name)
        {
            case 'firstname':
                return $this->firstname;
                break;

            case 'lastname':
                return $this->lastname;
                break;

            default:
                            # By throwing Exception for undefined property we can enforce strict property definition rules
                            # we also achive better error messages for improved debugging during development
                            # this is necessare because of lack of support for strict properties in php 5.3.15
                            $error = "Error: __get property: " . $name . " not supported by class: " . __CLASS__ ;
                                        throw new Exception($error);
                                        break;
        }
        return null;
    }

        */
        /*
        * a String representation for all Persons.
        */
        public function __toString()
        {
                return "Firstname: $this->firstname , Lastname: $this->lastname";
        }
}


?>

<?php


        try
        {
                # create a PHP Array and initialize it with Person objects
                $persons = array
                (
                        new Person("Fredrik", "Framberg"),
                        new Person("Greta", "Gavelstam"),
                        new Person("Urban", "Urberg"),
                        new Person("Anna", "Ambtesteg")
                        new Person("Henrik", "Hammarberg"),
                        new Person("Kristina", "Karlestam"),
                        new Person("Hans", "Hallin"),
                        new Person("Berit", "Bygdén")
                );

                # print out the results - calls Person->__toString().
                foreach($persons as $person) echo "$person<br>\n";
        }
        catch (Exception $e)
        {
                echo 'Caught exception: ',  $e->getMessage(), "\n";
        }

?>


Weaver 2012-07-23 20:46

Vad får du för felmeddelande?

jonny 2012-07-23 20:50

Om du skriver korrekta kommentarer och lägger till det kommatecken som saknas så ser det ut att fungera.

Kod:

<?php
class Person
{
    private $firstname;
    private $lastname;

        public function __construct($pFirstname, $pLastname)
        {
                $this->firstname = $pFirstname;
                $this->lastname = $pLastname;
        }

    public function __set($name, $value)
    {
        switch ($name)
        {
            case 'firstname':
                $this->firstname = $value;
                break;

            case 'lastname':
                $this->lastname = $value;
                break;

            default:
                            # By throwing Exception for undefined property we can enforce strict property definition rules
                            # we also achive better error messages for improved debugging during development
                            # this is necessare because of lack of support for strict properties in php 5.3.15
                            $error = "Error: __set property: " . $name . " not supported by class: " . __CLASS__ ;
                                        throw new Exception($error);
                                        break;
        }
    }

    public function __get($name)
    {
        switch ($name)
        {
            case 'firstname':
                return $this->firstname;
                break;

            case 'lastname':
                return $this->lastname;
                break;

            default:
                            # By throwing Exception for undefined property we can enforce strict property definition rules
                            # we also achive better error messages for improved debugging during development
                            # this is necessare because of lack of support for strict properties in php 5.3.15
                            $error = "Error: __get property: " . $name . " not supported by class: " . __CLASS__ ;
                                        throw new Exception($error);
                                        break;
        }
        return null;
    }

        /*
        * a String representation for all Persons.
        */
        public function __toString()
        {
                return "Firstname: $this->firstname , Lastname: $this->lastname";
        }
}


?>

<?php


        try
        {
                # create a PHP Array and initialize it with Person objects
                $persons = array
                (
                        new Person("Fredrik", "Framberg"),
                        new Person("Greta", "Gavelstam"),
                        new Person("Urban", "Urberg"),
                        new Person("Anna", "Ambtesteg"),
                        new Person("Henrik", "Hammarberg"),
                        new Person("Kristina", "Karlestam"),
                        new Person("Hans", "Hallin"),
                        new Person("Berit", "Bygd‚n")
                );

                # print out the results - calls Person->__toString().
                foreach($persons as $person) echo "$person<br>\n";
        }
        catch (Exception $e)
        {
                echo 'Caught exception: ',  $e->getMessage(), "\n";
        }

?>


Conny Westh 2012-07-24 00:34

Nu har jag fått till det som jag vill ha det, ett tydligt felmeddelande när man använder odefinierade egenskaper på en klass (det borde vara inbyggt i ett objektorienterat språk):

Kod:

<?php
class Person
{
    private $firstname;
    private $lastname;

        public function __construct($pFirstname, $pLastname)
        {
                $this->firstname = $pFirstname;
                $this->lastname = $pLastname;
        }

    public function __set($name, $value)
    {
        switch ($name)
        {
            case 'firstname':
                $this->firstname = $value;
                break;

            case 'lastname':
                $this->lastname = $value;
                break;

            default:
                            # By throwing Exception for undefined property we can enforce strict property definition rules
                            # we also achive better error messages for improved debugging during development
                            # this is necessary because of lack of support for strict properties in php 5.3.15
                            $error = "Error: __set property: " . $name . " not supported by class: " . __CLASS__ ;
                                        throw new Exception($error);
                                        break;
        }
    }

    public function __get($name)
    {
        switch ($name)
        {
            case 'firstname':
                return $this->firstname;
                break;

            case 'lastname':
                return $this->lastname;
                break;

            default:
                            # By throwing Exception for undefined property we can enforce strict property definition rules
                            # we also achive better error messages for improved debugging during development
                            # this is necessary because of lack of support for strict properties in php 5.3.15
                            $error = "Error: __get property: " . $name . " not supported by class: " . __CLASS__ . ".";
                                        throw new Exception($error);
                                        break;
        }
        return null;
    }

        /*
        * a String representation for all Persons.
        */
        public function __toString()
        {
                return $this->firstname . " " . $this->lastname;
        }
}


?>

<?php

        $rad = 0;
        try
        {
                echo "\nTest of errormessage wehen faulty property ...\n";
                echo "(row) - Firstname Lastname\n";
                # create a PHP Array and initialize it with Person objects
                $persons = array
                (
                        new Person("Fredrik", "Framberg"),
                        new Person("Greta", "Gavelstam"),
                        new Person("Urban", "Urberg"),
                        new Person("Anna", "Ambtesteg"),
                        new Person("Henrik", "Hammarberg"),
                        new Person("Kristina", "Karlestam"),
                        new Person("Hans", "Hallin"),
                        new Person("Berit", "Bygdén")
                );

                # print out the results - calls Person->__toString().
                foreach($persons as $person) echo "(" . ++$rad . ") - " . "$person\n";
        }
        catch (Exception $e)
        {
                echo 'Caught exception (1): ',  $e->getMessage(), "\n";
        }

        try
        {
                echo "\nTest of creating new object of class Person ...\n";
                $faultyPerson = new Person("Dennis","Harper");
                echo "This message will hopefully be written to console.\n";
        }
        catch (Exception $e)
        {
                echo 'Caught exception (2): ',  $e->getMessage(), "\n";
        }

        try
        {
                echo "\nTest of errormessage when faulty __set property ...\n";
                echo "(" . ++$rad . ") - " . "$faultyPerson\n";
                $faultyPerson->Age = 34;
                $faultyPerson->ShoeSize = 45;
                echo "Age: " . $faultyPerson->Age . " years.\n";
                echo "ShoeSize: " . $faultyPerson->ShoeSize . ".\n";

                echo "This message will not be written to console.\n";

        }
        catch (Exception $e)
        {
                echo 'Caught exception (3): ',  $e->getMessage(), "\n";
        }

        try
        {
                echo "\nTest of errormessage when faulty __get property ...\n";
                echo "(" . ++$rad . ") - " . "$faultyPerson\n";
                echo "ShoeSize: " . $faultyPerson->ShoeSize . ".\n";
                echo "Age: " . $faultyPerson->Age . " years.\n";

                echo "This message will not be written to console.\n";

        }
        catch (Exception $e)
        {
                echo 'Caught exception (4): ',  $e->getMessage(), "\n";
        }

        echo "\nDone testing class: Person.\n---------------------------------------\n\n";
?>


HenrikAI 2012-07-24 09:57

Edit: äh, glöm det....

HenrikAI 2012-07-24 10:02

Edit: glöm det...

orreborre 2012-07-24 12:21

Nu vet jag inte vad du egentligen är ute efter men att behöva ange alla godkända egenskaper i __set och __get känns omständigt.

Jag skulle gjort såhär: http://pastebin.com/ZDzJM0NL

Och för att lägga till nya egenskaper som ska kunna sättas definierar du först scopet och sen sätter dem till något defaultvärde i konstruktorn.


Alla tider är GMT +2. Klockan är nu 22:29.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson