MNH Gedankensprudel

nicht nur ein stilles Wasser

PHP wir spielen mit Referenzen

11.02.12 (Tutorial´s)

Wer mal mit C oder C++ gearbeitet hat kennt ein ähnliches Modell bereits die Pointer. Allerdings da PHP ja eine Scriptsprache ist stellt es keine Speicheradressen zur Verfügung.

Dafür haben wir aber Referenzen die zwar keinen Performance voreilt verschaffen dafür aber einen ähnliche Möglichkeiten zur Manipulation der Variablen bietet (von der Arithmetik mal abgesehen).

ein kleines Beispiel habe ich mal hier zusammengestellt ziel war es eine Wrapperklasse für Strings zu erstellen .

global $counter, $memory;
$counter = 0;
$memory = array();
function &getNewReference($dataType) {
    global $counter;
    global $memory;
    do {
	    $name = 'RefKey'.$counter++;

    } while (isset($memory[$name]));

    $memory[$name] = $dataType;

    if(is_object($dataType) && in_array('setRefKey', get_class_methods($dataType))) {
	    $dataType->setRefKey($name);
    }
    return $memory[$name];
}
 
class String{
    private $value;
    private $refKey;

    public function setRefKey($name) {
	$this->refKey = $name;
    }

    public function __construct($value = null){
	$this->value = $value;
    }

    public static function &string($value = null) {
	// Übergibt eine Referenz auf die Funktion  getNewReference,
	// die ihreseits eine Referenz auf das $memory Array übergibt
	$string = &getNewReference(new String($value));
	return $string;
    }

    public function __toString() {
	return (string) $this->value;
    }
    public function __destruct() {
	global $memory;

	// Kann sofort zerstört werden da keine Referenz.
	 if($this->refKey === null) {
	    return;
	}
		// Prüfen ob ein Object gleichen types in die referenz geschrieben wurde.
	if($memory[$this->refKey] instanceof self) {
			// Neuen object alten Referenzkey übertragen.
	    $memory[$this->refKey]->setRefKey($this->refKey);
			// Ist es eine skalaren Variable ("Normaler Datentyp" string, int , bool, usw..)".
	} else if(is_scalar($memory[$this->refKey])){
			// Neuen wert aus der Referenz auslesen.
	    $value = $memory[$this->refKey];
			// Eigene Classe ermittel (für extended).
	    $class = get_class($this);;
	    // Neues Object erzeugen und in das Array mit den Referenzen schreiben
	    $memory[$this->refKey] = new $class($value);
			// Neuen object alten Referenzkey übertragen.
	    $memory[$this->refKey]->setRefKey($this->refKey);
	}
    }
}
$foo = & String::string();

$foo = 'Hallo Welt!';

$bar = & String::string();

$bar = 42;

var_dump($foo);

echo $foo.' Der sinn des Lebens ist '. $bar;
Carschrotter
ist leidenschaftlicher Technik Fan beigester von allen was mit dem Web zu tuen hat und Vollblut Nerd. Deshalb war auch sein Ausbildung zum Fachinformatiker ein logischer schritt.

2 Kommentare

  • 1
    Jan Richter:

    Wenn ich Ihren Code richtig verstehe erhalte ich also einen simplen Autoboxing Mechanismus, der immer wieder neue Kopien des Objekts erstellt?

  • 2
    Carschrotter:

    Hallo, im Prinzip ja und dadurch das wir eine Referenz zurückgeben merkt der „Benutzer“ dafon nichts da die Variable immer ein Object enthält. Wer soetwas ernsthaft verwenden möchte dem empfhle ich alerdings SPL_Typs als erfweiterung dort geht dan auch sowas wie $obj =+ "string";

Kommentar schreiben

XHTML: Sie können diese Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre prompt="" escaped="">