phpbar.de logo

Mailinglisten-Archive

[php] oohforms - add_element - $cv_tab

[php] oohforms - add_element - $cv_tab

Ulf Wendel ulf_(at)_redsys.de
Thu, 20 Jan 2000 03:20:23 +0000


Peter Kühn wrote:
> 
> > > Warning: Uninitialized variable or array index or property (checkbox) in
> > > oohforms.inc on line 175
> >
> > Was steht denn in den genannten Zeilen drin?
> 
> s. den hilfreichen Einwand von Egon: eigentlich sind das keine echten
> Fehlermeldungen sondern nur Warnhinweise. Means: irgendwas ist zwar nicht die
> reine Lehre, max aber nix - echte böse Fehler lauten folgerichtig irgendwas
> mit "Error" (richtig verstanden Egon?)

"Richtige" Fehler spucken ein Error. Warning soll auf eine unsaubere
oder möglicherweise falsche Programmierung hinweisen. Doch was bedeutet
"unsauber"?

PHP hat weder streng getypte Variablen noch verlangt es nach einem
strengen Verfahren von Definition und Initialisierung, wenn eine neue
Variable benötigt wird. 

+++ Variablen "anmelden" +++

Variablen stehen in PHP "einfach so zur Verfügung". Dies ist vielen
Sprachen anders. Eine Variable benötigt Speicher, weshalb viele Sprachen
(C, C++, Pascal, Java) die "Anmeldung" einer neuen Variable
vorschreiben. Diese Anmeldung besteht aus zwei Schritten. Der Definition
zur Festlegung des Typs und der Initialisierung, um der Variablen einen
Wert zuzuweisen. Bei der Definition wird ein entsprechend des Typs
benötigter Speicherbereich für die Variable reserviert. Bei der
Initialisierung werden die zufälligen Daten im reservierten Speicher
überschrieben mit dem neuen Wert überschrieben.

PHP verfolgt als Skriptsprache wie BASIC (beginners all supposed
instructions code) einen anderen Ansatz, den viele Einsteiger einfacher
finden. Eine Variable hat (meist) keinen festen Typ und stets einen
erwarteten Anfangswert (String "", Zahl 0). Dies verbirgt Komplexität
und beseitigt eine der häufigsten Fehlerquellen bei Anfängern. Außerdem
entspricht das Verhalten, dem was der Laie erwartet. 

Will man sauber programmieren muß man also eine Variable mit zur
Verwendung "anmelden", etwa so:
$elements = array();  # Definition und Initialisierung in einem

+++ Typen +++

Der Einsteiger schreibt mal $zahl = "1", mal $zahl = 1 und erwartet, daß
beide Varianten das gleiche Ergebnis liefern, wenn man später $zahl mal
als mal als Text (PHP: string), mal als Zahl (PHP: integer oder double)
verwendet.

$zahl = "1";        	                        # $zahl ist ein string
echo 'Typ von $zahl: '.gettype($zahl)."<br>\n"  # Typ von $zahl ausgeben
(string)
$zahl = $zahl + 3;                              # $zahl wie eine Zahl
verwenden...

funktioniert in PHP genauso wie:

$zahl = 1;                                      # $zahl ist ein integer
echo 'Typ von $zahl: '.gettype($zahl)."<br>\n"  # Typ von $zahl ausgeben
(integer)
$zahl=$zahl." wie ein String...";               # $zahl wie einen Text
behandeln...

Um uns diese Toleranz bieten zu können, haben die Core Developer sich
entschieden intern jede Variable in allen benötigten Varianten zu
speichern. Wenn ich es richtig weiß - bitte korrigiert mich, was den
Zeitpunkt der Speicherallozierung betrifft -, wird bei jedem Auftreten
einer PHP Variable der benötigte Typ erzeugt und in der internen
Hashtable gespeichert. Dies bedeutet, daß bei $zahl = "1" zunächst
Speicher für einen String reserviert wird und spätestens nach einem
$zahl++ auch für einen Integer. 

Entsprechend führen massive Typwechsel zu einem geringen
Performanceverlust, aber wer würde schon folgendes schreiben (~ -8%) ?

for ($i=0; $i<100000; $i++) {
  $zahl = "1";
  $zahl++;
}

+++ Warum Typen? +++

Streng typisierte Variablen haben auch Vorteile. U.a. verbrauchen sie
weniger Speicher, decken Fehlbenutzungen auf und vermeiden solch lustige
Dinge wie "===" als Operator,
http://www.php.net/manual/language.operators.comparison.php3 .

+++ Warnings +++

Speicherallozierung, Typen, all das bleibt dem PHP Einsteiger weitgehend
erspart. Würde dem nicht so sein, könnten wir nicht mal ebend $zahl als
String und im nächsten Moment als Zahl behandeln. Wir müßten uns genau
an die Spielregeln halten. Es wäre auch streng verboten auf
Arrayelemente zuzugreifen, die gar nicht existieren. Genau so ein Fall
erzeugt obige Warnmeldung.

$element = array ("name" => "eissorte", "value" => "Schoko" );
echo $element["checked"];

Dieser Code meldet keinen Error, obwohl das Arrayelement "checked" nicht
existiert. C würde bei solch einem Versuch richtig sauer werden. PHP
generiert nur bei einem hohen Wert für das Error Reporting (
http://www.php.net/manual/function.error-reporting.php3 ) eine Warnung. 

"8 = Notices - warnings you can ignore, but sometimes imply a bug (e.g.,
using an uninitialized variable)", php3.ini-dist

> Neu war mir das (zitat Ulf) "Die gesamte PHPLIB spuckt Warnings".
> 
> =>Frage daher: belasten die Warnungen nicht irgendwie letztlich doch die
> Maschine (auch wenn sie mit error_reporting=7 unterdrückt werden)?

PHP nimmt stets eine Prüfung aller geparsten Variablen vor. Ganz egal,
ob die Variable vorher "angemeldet" wurde oder nicht. Die wenigen Zeilen
C-Code zur Speicherung eines Warnhinweises sind nicht meßbar.

Man könnte geneigt sein, folgende Varianten gegeneinander auszumessen.

(1)
for ($i=0; $i<100000; $i++) {
  $daten = array ( "name" => "test" );
  $daten["nixda"]++;
}
 
(2)
for ($i=0; $i<100000; $i++) {
  $daten = array ( "name" => "test", "nixda" => 0 );
  $daten["nixda"]++;
}

Die zweite Variante ist einen Hauch langsamer, obwohl sie im Gegensatz
zur ersten Variante keine Warnings erzeugt. 

Warum? Per Definition ist es in PHP nicht notwendig Variablen
"anzumelden". Es besteht praktisch kein Geschwindigkeitsunterschied
zwischen der Verwendung bereits definierter oder bislang undefinierter
Variablen. Spürbar ist jedoch der erhöhte Zeitverbrauch des Parsers in
der unteren Variante. Sieht der Code wie folgt aus, ist der
Geschwindigkeitsunterschied weg.

for ($i=0; $i<10000; $i++) {
  $daten = array();
  for ($j=0; $j<20; $j++)
    $daten["foo_$j"]="foo_$j";
  # mit $daten["nix_da"] = 0 tauschen, Zeilenanzahl identisch lassen!
  $daten["dummie"] = $j;        
  # nicht ändern...
  $daten["nix_da"]++;
}


+++ Warum dann Warnings +++

Warnings geben hilfreiche Informationen für das Debuggen der eigenen
Skripte. Arbeitet man mit komplexen Arrays und greift durch einen
Tippfehler auf ein nicht existierendes Element zu, liefert PHP einen
Hinweis.

if (""!=$element["namE"])
  ...

Bei komplexeren Skripten hilft es nicht zuletzt bei der Dokumentation.
Gnadenlos werden Variablen gefunden, die zuvor nicht deklariert wurden.
Und bei der Deklaration sollte stets ein kurzer Kommentar stehen. Dieser
Code ist unglücklich und produziert Warnhinweise:

class bla {
  function get() {
    return $this->elemente;
  }
}

$b = new bla;
$elemente = $b->get();

So macht man es besser und kommt prompt ohne Warnungen aus:

class bla {
 var $elemente = array();   # Alle Elemente der OOHForms
 function get() {
   return $this->elemente;
 }
}


Ulf


php::bar PHP Wiki   -   Listenarchive