Datei wird beschrieben, obwohl mit "r"-flag geöffnet?!

Datei wird beschrieben, obwohl mit "r"-flag geöffnet?!

am 17.10.2006 14:16:44 von Andreas Weishaupt

Hallo zusammen

Ich kapier's wirklich nicht mehr, bin seit Tagen daran, nach Fehlern zu
suchen und werde ständig auf's Neue verblüfft. Erreichen will ich
eigentlich Folgendes (neben dem Auffrischen einiger PHP-Kenntnisse): Es
werden Filme (resp. besser: Filmnamen) in einer Datei verwaltet, zu
jedem Film noch wer (online user) ihn gesehen hat und wer nicht; jeder
online user kann selbst einen Film hinzufügen oder einen entfernen und
bei den schon vorhandenen anklicken, wenn er ihn bereits gesehen hat.

Mein Problem ist nun nicht, dass das Hinzufügen und Löschen etc. nicht
klappt, sondern dass die falschen Meldungen dazu angezeigt werden (z.B.
nach erfolgreichem Löschen steht: "... konnte nicht gelöscht werden",
dazelbe beim Hinzufügen). Diese Falschmeldungen haben mich schliesslich
dazu veranlasst, etwas genauer zu untersuchen, was eigentlich vorsich
geht beim Ausführen des Codes. Und nun komme ich zu der seltsamen
Auffassung, dass die Datei, in der die Informationen betreffend den
Filmen stehen, beschrieben wird, bevor ich überhaupt zum ersten mal auf
sie zugreiffe (und das auch noch per "r"-flag in fopen())! Ich habe den
Verdacht, dass irgendwie Servereinstellungen o.ä. an diesem Verhalten
Schuld sind. Code-mässig sieht das Ganze so aus:


--- Datei movlist.php ---


// ..... nicht von mir ...
bmc_Template('page_header', "Filmklassiker");
include_once "movfunc.php"; // nur diese Zeile
bmc_Template('page_footer');

?>



--- Datei movfunc.php ---


require_once "movfunc.inc.php";
if (isset ($_GET['mov_action'])) {
if ($_GET['mov_action'] == "add") {
if (isset ($_GET['movadd'])) {
$movname = trim ($_GET['movadd']);


// siehe Kommentar unten *1

if (!isset ($arrMovList)) { echo "

\$arrMovList nicht
gesetzt!

"; }
$arrMovList = movGetList();
if (!array_key_exists ($movname, $arrMovList)) {
movAddToList ($arrMovList, $movname, $user_info['id']);
echo "

Film erfolgreich hinzugefügt!

\n";
}
else {
echo "

Fehler: \"$movname\" konnte nicht
hinzugefügt werden. ";
echo "Vielleicht schon vorhanden?

\n";
}
}
}
else if ($_GET['mov_action'] == "delete") {
if (isset ($_GET['movdel'])) {
$movname = trim ($_GET['movdel']);
$arrMovList = movGetList();
if (array_key_exists ($movname, $arrMovList)) {
movDelFromList ($arrMovList, $movname);
echo "

\"{$_GET['movdel']}\" wurde gelöscht!

";
}
else {
echo "

Fehler: \"$movname\" konnte nicht
gelöscht werden.";
}
}
}
else if ($_GET['mov_action'] == "save") {
if (isset ($_GET['movseen']) && is_array ($_GET['movseen'])) {
movSaveEval ($arrMovList, $_GET['movseen'], $user_info['id']);
}
else {
echo "

Fehler: Problem beim Speichern der
Einstellungen.

";
}
}
}
?>










$arrMovList = movGetList();
foreach ($arrMovList as $name => $arrids) {
$name = trim ($name);
$htmlname = htmlspecialchars ($name);
echo "\n";
echo "\n";
echo "";
echo "\n";
echo "\n";
}
?>






MOVIE NAME ADDED BY (ID)
href=\"{$_SERVER['PHP_SELF']}?mov_action=delete&movdel=$ htmlname\">$htmlname{$arrids[0]} value=\"$htmlname\"";
if (in_array ($user_info['id'], $arrMovList[$name]) &&
$user_info['id'] != $arrids[0]) {
echo " checked=\"checked\">";
}
else {
echo ">";
}
echo "
onclick="this.form.mov_action.value='save'; this.form.submit()">    

Film hinzufügen:
onclick="this.form.mov_action.value='add'; this.form.submit()">







--- Datei movfunc.inc.php ---



define ("MOV_LIST_FILE", "addons/movies.dat");


// create the overview from the list
// remember, line format is: [mov.name] | [id0] [id1] [id2] [id3] [...]
// the id's mentioned belong the user's who haven't seen the
corresponding movie
// id0 belongs to the user who has added the movie
function trimArrElements (&$val, &$key) {
$val = trim ($val);
}


// siehe Kommentar unten *2

function movGetList() {
$fp = fopen (MOV_LIST_FILE, "r");
if ($fp) {
echo "

" . MOV_LIST_FILE . " has been opened.
";
while (!feof ($fp)) {
$tline = fgets ($fp);
if ($tline != "") {
echo "new line: '$tline'
";
$tarrMov = explode ("|", $tline);
$tarrIds = explode (" ", trim ($tarrMov[1]));
$tindex = trim ($tarrMov[0]);
$tarrMovList[$tindex] = $tarrIds;
array_walk ($tarrMovList[$tindex], 'trimArrElements');
}
}
echo "

";
}
fclose ($fp);
return $tarrMovList;
}

function movAddToList (&$list, $name, $id) {
$list = $list + array ($name => array ("$id", "$id"));
movSaveList ($list);
}

function movDelFromList (&$list, $name) {
unset ($list[$name]);
movSaveList ($list);
}

function movSaveList ($list) {
$fp = fopen (MOV_LIST_FILE, "w");
if ($fp) {
foreach ($list as $name => $ids) {
$idlist = implode (" ", $ids);
fputs ($fp, "$name | $idlist\n");
}
}
fclose ($fp);
}

function movSaveEval ($list, $seen, $id) {
// recreate movie list
foreach ($seen as $k => $name) {
if (!in_array ($id, $list[$name]) || $list[$name][0] == $id) {
$list[$name][] = $id;
}
}
// then save it
movSaveList ($list);
}

?>

--- Ende der Dateiauszüge ---


*1 vor dem ersten Aufruf von getMovList() prüfe ich mit isset(), ob das
Array $arrMovList bereits existiert. Aber dies ist - wie erwartet -
jeweils nicht der Fall!

*2 innerhalb getMovList() habe ich einige Debugausgabe-Zeilen eingebaut.


Gebe ich nun im Formular für Film-Hinzufügen irgendwas an, was
garantiert noch nicht in der Liste steht und klicke ich auf
"Hinzufügen", so erscheinen dann folgende Meldungen:


$arrMovList nicht gesetzt!

addons/movies.dat has been opened.
new line: 'Pulp Fiction | 3 5 7 9 '
new line: 'Apocalypse Now | 3 3 '
new line: 'Kill Bill | 3 3 '
new line: 'The Godfather | 3 3 '
new line: 'fdhkjg dsjhf sdjdshlg j | 3 3 '

Fehler: "fdhkjg dsjhf sdjdshlg j" konnte nicht hinzugefügt werden.
Vielleicht schon vorhanden?

addons/movies.dat has been opened.
new line: 'Pulp Fiction | 3 5 7 9 '
new line: 'Apocalypse Now | 3 3 '
new line: 'Kill Bill | 3 3 '
new line: 'The Godfather | 3 3 '
new line: 'fdhkjg dsjhf sdjdshlg j | 3 3 '


Wir haben also ganz klar $arrMovList nicht gesetzt, anschliessend folgt
der Aufruf von getMovList(), die die Datei eindeutig mit "r" öffnet,
aber behauptet, "fdhkjg dsjhf sdjdshlg j" sei schon in der Datei und
deshalb anschliessend auch der Versuch mit array_key_exists fehlschlägt
und die falsche Fehlermeldung ausgegeben wird.
Wir wie zum Teufel kommt "fdhkjg dsjhf sdjdshlg j" in die Datei und zwar
vor (oder während) dem ersten Aufruf von getMovList()???

Werdet ihr schlau daraus?


Schönen Tag

Andreas

Re: Datei wird beschrieben, obwohl mit "r"-flag geöffnet?!

am 17.10.2006 14:25:16 von Martin Kaffanke

Am Tue, 17 Oct 2006 14:16:44 +0200 schrieb Andreas Weishaupt:

> beschrieben wird, bevor ich überhaupt zum ersten mal auf
> sie zugreiffe (und das auch noch per "r"-flag in fopen())!

[mächtig viel Code]

Wäre supa, wenn du das mal minimalisierst und so zum Testen freigibst,
also nur datei mit r öffnen und einen write versuchen.

lg,
Martin

Re: Datei wird beschrieben, obwohl mit "r"-flag geöffnet?!

am 17.10.2006 16:04:25 von Ulf Kadner

Andreas Weishaupt schrieb:

> Mein Problem ist nun nicht, dass das Hinzufügen und Löschen etc. nicht
> klappt, sondern dass die falschen Meldungen dazu angezeigt werden (z.B.
> nach erfolgreichem Löschen steht: "... konnte nicht gelöscht werden",
> dazelbe beim Hinzufügen). Diese Falschmeldungen haben mich schliesslich
> dazu veranlasst, etwas genauer zu untersuchen, was eigentlich vorsich
> geht beim Ausführen des Codes. Und nun komme ich zu der seltsamen
> Auffassung, dass die Datei, in der die Informationen betreffend den
> Filmen stehen, beschrieben wird, bevor ich überhaupt zum ersten mal auf
> sie zugreiffe (und das auch noch per "r"-flag in fopen())!

Nein es passiert nur das was Dein Code macht! :-)

>




sonst kann man z.B. so Javascript einschleusen:
/tests/simple.php/%22%3E%3Cscript%3Ealert('Pöse')%3C/script% 3E%3Cfoo

> function trimArrElements (&$val, &$key) {
> $val = trim ($val);
> }

sehr sinnvolle Funktion... :-)

> function movSaveList ($list) {
> $fp = fopen (MOV_LIST_FILE, "w");

hier wird doch geschrieben! Debug doch einfach diese stelle, dann kennst
Du die Aufrufe. Unter PHP5 kannste dort auch ohne Debugger ne Exception
erstellen und im Backtrace nachschauen wo der aktuelle Aufruf herkommt.

> $arrMovList nicht gesetzt!
>
> addons/movies.dat has been opened.
> new line: 'Pulp Fiction | 3 5 7 9 '
> new line: 'Apocalypse Now | 3 3 '
> new line: 'Kill Bill | 3 3 '
> new line: 'The Godfather | 3 3 '
> new line: 'fdhkjg dsjhf sdjdshlg j | 3 3 '
>
> Fehler: "fdhkjg dsjhf sdjdshlg j" konnte nicht hinzugefügt werden.

Das sind alles Fehler die in Deinem Code gesetzt werden. Da muste schon
selbst rausfinden was wo falsch ist oder Du reduzierst den aufs
minimalste. Deine Codeverwurstungen zu korrigieren hat hier sicher
keiner Ambitionen.

> Wir haben also ganz klar $arrMovList nicht gesetzt, anschliessend folgt

Schreibst Du gern von Dir in der Mehrzahl? :-)

MfG, Ulf

Re: Datei wird beschrieben, obwohl mit "r"-flag geöffnet?!

am 17.10.2006 16:34:30 von thorny

Ulf Kadner schrieb:

>>function movSaveList ($list) {
>> $fp = fopen (MOV_LIST_FILE, "w");
>
>
> hier wird doch geschrieben! Debug doch einfach diese stelle, dann kennst
> Du die Aufrufe. Unter PHP5 kannste dort auch ohne Debugger ne Exception
> erstellen und im Backtrace nachschauen wo der aktuelle Aufruf herkommt.

Oder falls er PHP 4.3 ++ hat, kann man auch debug_backtrace() verwenden.

Gruß,
Torsten

Re: Datei wird beschrieben, obwohl mit "r"-flag geöffnet?!

am 17.10.2006 19:16:21 von Andreas Weishaupt

Ulf Kadner schrieb:

> Nein es passiert nur das was Dein Code macht! :-)
>
> >
> sonst kann man z.B. so Javascript einschleusen:
> /tests/simple.php/%22%3E%3Cscript%3Ealert('Pöse')%3C/script% 3E%3Cfoo

Danke, werd' ich mir merken (und natürlich auch, dass immer nur das
passiert, was Mein Code macht! ;-))

>>function trimArrElements (&$val, &$key) {
>> $val = trim ($val);
>>}
> sehr sinnvolle Funktion... :-)

Sowas kommt vor, wenn man alle 6 Monate mal wieder ein Script basteln
will ;-)

>>function movSaveList ($list) {
>> $fp = fopen (MOV_LIST_FILE, "w");
>
> hier wird doch geschrieben! Debug doch einfach diese stelle, dann kennst
> Du die Aufrufe. Unter PHP5 kannste dort auch ohne Debugger ne Exception
> erstellen und im Backtrace nachschauen wo der aktuelle Aufruf herkommt.

So logisch wie auch immer dein Tipp klingt, ich wär' in der nächsten
Zeit wohl nicht darauf gekommen, einfach diese Stelle zu debuggen...

> Das sind alles Fehler die in Deinem Code gesetzt werden. Da muste schon
> selbst rausfinden was wo falsch ist oder Du reduzierst den aufs
> minimalste. Deine Codeverwurstungen zu korrigieren hat hier sicher
> keiner Ambitionen.

Ja, ich habe ihn nachmittags bereits in Minimalstform gehabt und der
Fehler war nicht mehr da. Bin bei der Entwicklung zu überstürzt und
unüberlegt vorgegangen und habe einfach geschrieben, geschrieben und
geschrieben, ohne ein einziges mal zu testen - zzz, was sagt man dazu...?!
Aber nun kommt doch noch alles ins Lot!

> Schreibst Du gern von Dir in der Mehrzahl? :-)

In einer News_gruppe_ will man ja nicht gerne alleine da stehen. ;-)


Besten Dank für eure Hilfe und
viu Grüess us Bärn