phpbar.de logo

Mailinglisten-Archive

[php] kaputter String ( was: Array mit String überschreiben - Bug?)

[php] kaputter String ( was: Array mit String überschreiben - Bug?)

Johannes Schlueter schlueter at phpbar.de
Sam Jun 5 20:37:12 CEST 2004


Hi Peter,

On Saturday 05 June 2004 18:59, Peter Bieling wrote:
> es geht mir nicht um diese "\0"-Geschichte, sondern darum, dass ein

Doch ;-)

<?php
$string = "foo";
$len = strlen($string);

echo $string.":\n";
for ($i = 0; $i<$len; $i++) {
    printf("%u => %u\n", $i, ord($string{$i}));
}

$string{1} = '';

echo $string.":\n";
for ($i = 0; $i<$len; $i++) {
    printf("%u => %u\n", $i, ord($string{$i}));
}
?>
foo:
0 => 102
1 => 111
2 => 111
fo:
0 => 102
1 => 0
2 => 111

Durch die _Zuweisung_ von nichts ('') auf $string{1} wird da das entsprechende 
Zeichen nicht gelöscht sondern durch nichts ersetzt. Nichts wird dabei durch 
NULL, also das Zeichen mit Ascii-Wert 0 repräsentiert.



Nur weil ich mich gerade nicht zurück halten konnte mal wieder den C-Compiler 
nazuwerfen: Wie verhalten sich "ordentliche" Programmiersprachen wie z.B. C?

#include <stdio.h>

int main() {
    int i;
    char string[] = "foo";
    int len = strlen(string);


    printf("%s:\n", string);
    for (i=0; i<=len; i++) {
        printf("%u => %u\n", i, string[i]);
    }

    string[1] = "";
    printf("%s:\n", string);
    for (i=0; i<=len; i++) {
        printf("%u => %u\n", i, string[i]);
    }
}

Da gibt der gcc gleich mal eine Warnung aus:
test.c:14: warning: assignment makes integer from pointer without a cast
Korrekt wäre die Zuweisung string[1] = '\0'; ich wollte es aber möglichst 
analog zum PHP-Script haben...
Und einen weiteren unterschied habe ich aber noch drin und zwar geht die 
anzeigende for-Schleife von 0 bis $i<$len wohingegen bei der C-Version die 
Schleife von 0 bis i<=len geht, ganz einfach weil Strings in C 
Null-terminiert sind und das \0 am Ende noch dazugehört, strlen das aber als 
Ende interpretiert. Bei PHP hört er wirklich "am Ende" auf.

foo:
0 => 102
1 => 111
2 => 111
3 => 0
fo:
0 => 102
1 => 4294967191         // Bei string[1] = '\0'; stünde hier 0
2 => 111
3 => 0

Ergebnis: Auch bei "ordentlichen" Programmiersprachen kann man nicht einfach 
ein Zeichen mit "nichts" überschreiben und somit Teile aus dem String kürzen. 
Wenn ich _ein_ Zeichen bearbeite will ich, dass auch nur _ein_ Zeichen 
beabeitet wird. Wenn ich "Wechselwirkungen" mit anderen Zeichen zulassen will 
nutze ich substr oder ähnliches, die darauf Rücksicht nehemen.

<?php
$string = 'foo';
$string{1} = 'bar'; 
echo $string;
?>

Gibt ja auch "fbo" und nicht "fbar" aus.

johannes

php::bar PHP Wiki   -   Listenarchive