Autor Zpráva
smiesek
Profil
Můžete mi prosím poradit, proč se mi následující napsaný kód chová tak, že porovnává pouze poslední záznam v souboru? Resp. u něj jediného platí true, že je v poli.

Jde mi o vytvoření kodu, kdy pokud se narazí na stejnou hodnotu v souboru, aby byla smazána nebo přejmenována, ale to není nyní tak důležité jak to, že true platí jen pro poslední záznam

    // zjištění, zdali se shodují data, pokud ano, tak jej smazat
    if(file_exists("maillist.txt")) {
        $pole = file("maillist.txt"); // načtení každého řádku souboru do pole
        $email_new = $email; // přiřazení zadaného e-mailu z formuláře do nové pomocné proměnné pro porovnání
        $retez = ""; // inicializace proměnné
        foreach($pole AS $index => $hodnota) { // procházení jednotlivých položek
            print_r ($hodnota); // výpis hodnot polí pro ladění chyb
            if($hodnota==$email_new) {
                echo "Hodnota <strong>" .$hodnota. "</strong> již existuje!</p>";
                //unset($hodnota); // zruší proměnnou v souboru
            }
            if(isset($hodnota)) {
                $retez .=$hodnota;
            }
        }
        $otevri = fopen("maillist.txt", "w"); // otevření souboru pro vynulování a následně zápis
        fwrite($otevri,$retez);
        fclose($otevri);
        echo "Byli jste odhlášeni.</p>";
        exit;
    }

pokud si nechám pomocí print_r ($hodnota); vypsat pole, tak se mi všechny načtou, ale asi dělám chybu při procházení.
Nepožaduju finální řešení, spíše radu a navedení, ve které části se zaměřit na chybu.

Děkuji za váš čas a trpělivost.
juriad
Profil
smiesek:
file:
Returns the file in an array. Each element of the array corresponds to a line in the file, with the newline still attached.
Tedy problém je v tom, že porovnáváš email s koncem řádku a bez konce řádku. Pomohl by buď trim, nebo příznak FILE_IGNORE_NEW_LINES.

Mimochodem, toto lze řešit elegantněji:
define('MAILLIST', 'maillist.txt');

function seznam() {
        if (file_exists(MAILLIST)) {
                $emaily = file (MAILLIST,  FILE_IGNORE_NEW_LINES |  FILE_SKIP_EMPTY_LINES);
        } else {
                $emaily = array();
        }
        return $emaily;
}

function prihlas($email) {
        $emaily = seznam();
        $index = array_search($email, $emaily);
        if ($index === FALSE) {
                $emaily[] = $email;
                file_put_contents(MAILLIST, implode("\n", $emaily));
                return TRUE;
        }
        return FALSE;
}

function odhlas($email) {
        $emaily = seznam();
        $index = array_search($email, $emaily);
        if ($index !== FALSE) {
                unset($emaily[$index]);
                file_put_contents(MAILLIST, implode("\n", $emaily));
                return TRUE;
        }
        return FALSE;
}

Všimni si, že samotná funkce nic nikam nevypisuje vrací jen true/false podle toho, zda byl email přihlášen/ohlášen, nebo k žádné změně nedošlo.
Je lepší funkcionalitu a vstup/výstup oddělit. Kód je přehlednější a lépe se testuje (viz níže).

Pro otestování:
function result($b) {
        echo $b ? 'true' : 'false';
        echo "\n";
}

result( prihlas('a'));
result( prihlas('b'));
result( prihlas('c'));
result( odhlas('a'));
result( odhlas('a'));
result( odhlas('d'));
result( prihlas('a'));
result( prihlas('a'));

Mělo by vypsat:
true
true
true
true
false
false
true
false
smiesek
Profil
juriad:
aha, tak to se budu muset více zamyslet nad případným použitím Vašeho řešení, protože to mi bude dělat problém jednotlivé posloupnosti funkcí.

Mimo to, jsem to prozatím vyřešila dopsáním části jak jste naznačil
        $pole = file("maillist.txt", FILE_IGNORE_NEW_LINES |  FILE_SKIP_EMPTY_LINES); // načtení každého řádku souboru do pole
vše v pořádku, ale po úkonu se jakoby vše zbývající shlukne do jednoho pole.
Tedy asi nyní budu muset v některé části se zaměřit na funkci pro explode, aby se mi zpět rozdělil řetězec na polí?

Nebo je to špatně moje úvaha a postup? :(
juriad
Profil
smiesek:
Jde o to, že když použiješ FILE_IGNORE_NEW_LINES, tak nikde už nebudou konce řádků, a tedy příkaz na tvém řádku 13 slepí dva e-maily přímo za sebe. Musíš tam přidat odřádkování.
smiesek
Profil
juriad:
přidáno odřádkování a nyní tedy mi to ji neslepuje jednotlivé data.
Děkuju za pomoc a vysvětlení, v čem jsem dělala chybu.

Ostatně určitě Vaše řešení pomocí funkcí a rozdělení je elegantnější a ještě kdybych místo toho pracovala přímo s DB bude to bezpečnější, ale faktem je, proč se v tom takhle babrám, tak abych pochopila logiku práce se soubory, co se týká operací s jejich obsahem a právě mě jiný příklad nenapadl a co si teorii přečtu dle různých stránek se mi to ještě lépe chápe na reálném příkladu.

Tedy děkuju za trpělivost a budu doufat v pochopení i v případě dalších dílčích otázek týkající se php.

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: