ugrás a tartalomhoz

File beolvasás és mentés probléma

Theo76 · Már. 26. (K), 15.35
Sziasztok!

Egy adatbázis config file szerkesztő kódon dolgozok, de elakadtam...
A script egy formon keresztül kapja meg az új adatokat, mint pl az adatbázis nevét, felhasználót és jelszavát.
Eztután beolvassa az config file-t a file() utasítással, és a megfelelő soroknál kicseréli a szöveget, majd elmenti a file_put_contents()-el.
A gond az, hogy beolvassa a file-t, ki is cseréli a megfelelő sorokban a részeket, majd mikor elmenti, a módosítatlan szöveget menti el... Az érdekesség még, hogyha a file-t kézzel megváltoztatom, akkor is a legelőször beolvasott file tartalmát menti el...

A file tartalma pl.:

$config['db']['serverName'] = "";
$config['db']['serverUser'] = "";
$config['db']['serverPasswd'] = "";
a formon megadott adatok:
serverName: abc
serverUser: abc
serverPasswd: abc

mikor elmenti, marad a régi tartalom...
mikor kiíratom a beolvasott, és módosított tartalmat, ott semmi gond nincs...
új tartalom a változó kiíratásakor:

$config['db']['serverName'] = "abc";
$config['db']['serverUser'] = "abc";
$config['db']['serverPasswd'] = "abc";
Ezután kézzel módosítottam a config file-t:

$config['db']['serverName'] = "-";
$config['db']['serverUser'] = "-";
$config['db']['serverPasswd'] = "-";
A formban megadottak alapján újra szépen kicseréli a megadott karaktereket,
viszont mikor elmenti, akkor a legelső beolvasott tartalmat menti el...
Már újranéztem a változókat, újraindítottam a rendszert, de a legelső beolvasott file tartalma valahogy nagyon beakadt...

Mi állhat a háttérben?

Előre is köszönöm a segítséget!
 
1

Kód nélkül?

Endyl · Már. 27. (Sze), 11.39
Ha nincs kód, akkor csak annyit lehet mondani, hogy az áll a háttérben, hogy rossz a kódod :(

Gondolom nem onnan olvasol, vagy nem oda írsz, ahova gondolod. Esetleg nem azt, amit gondolsz.
2

Volt egy hozzászólásom, mikor

Theo76 · Már. 27. (Sze), 12.21
Volt egy hozzászólásom, mikor az volt a baj, hogy kódot írtam, ezért nem volt most... :)

Az egyes műveletek után próbáltam kiíratni, hogy mikor mik változnak, és minden teljesen rendben végrehajtódott.
A végén szándékosan hoztam létre másik file-t, mert én is kódhibára gyanakodtam, és így ellenőriztem, hogy mi lesz a végeredmény, de mindig ugyanaz...

...
$confFilePath = PROJECT_ROOT . 'config/dbConfig.inc';
$dbConfigFile = file( $confFilePath );

$searchConfigLine = [
    "serverType",
    "serverHost",
    "serverPort",
    "serverName",
    "serverUser",
    "serverPasswd"
];

foreach ( $dbConfigFile as $key => $line ) {
    foreach ( $searchConfigLine as $confLine ) {
        if ( stripos( $line, $confLine ) ) {
            $dbConfigFile[$key] = str_replace(
                                      fileTools::getConfigLineValue( $line ),
                                      "\"" . $_REQUEST[$confLine] . "\"", $line
                                  );
        }
    }
}

$dbConfigFile = implode( $dbConfigFile );

file_put_contents( $confFilePath . ".bak", $dbConfigFile );
3

Furcsa

Endyl · Már. 28. (Cs), 12.00
Ezek a sorok pont így szerepelnek a kódban, egy függvényen/scope-on belül? Nincsenek "szétszórva" több függvényben?

Nálam hibátalnul fut ebben a formájában.
4

Egy osztályban vannak a kódok

Theo76 · Már. 28. (Cs), 12.29
Igen... én is értetlenül állok előtte. Ez egy osztályon belül van, pont ebben a formában. Egyedül a kiíratosokat vettem ki. Csak a sorok feldolgozása (változók kicserélése) van átadva másik osztálynak. Nem lehet esetlegesen valami configurációs probléma?
5

Nem lehet, hogy függvények

Endyl · Már. 28. (Cs), 12.38
Nem lehet, hogy függvények között van átadva a $dbConfigFile, és egy kritikus helyen lemaradt egy &-jel?
6

Sajnos nem... Most átírtam

Theo76 · Már. 28. (Cs), 13.19
Sajnos nem... Most átírtam kicsit, hogy ne használja a $dbConfigFile, hanem a függvény, ami a sormódosításokat végzi, új változóba tegye.
Az első var_dump( $dbConfigFile ) kiírása szerint a fizikailag betöltött file tartalmazza a változó.
A második szerint tökéletesen elvégezte a módosításokat, majd mikor megnézem a létrehozott dbConfig.inc.bak file-t akkor a kód írásaokr előszőr beolvasott sorok vannak benne... A bak file-t próbáltam törölni, de mikor létrehozta, ugyan az az eredmény...

function defaultAction() {
    if ( !empty( $_REQUEST ) ) {
        $confFilePath = PROJECT_ROOT . 'config/dbConfig.inc';
        $newConfigFile = "";
        $dbConfigFile = [];

        $dbConfigFile = file( $confFilePath );
//eredeti config file tartalma
        var_dump( $dbConfigFile );

        $searchConfigLine = [
            "serverType",
            "serverHost",
            "serverPort",
            "serverName",
            "serverUser",
            "serverPasswd"
        ];

        foreach ( $dbConfigFile as $key => $line ) {
            $cLine = true;

            foreach ( $searchConfigLine as $confLine ) {
                if ( stripos( $line, $confLine ) ) {
                    $dbNewConfigFile[] = str_replace(
                        fileTools::getConfigLineValue( $line ), "\"" . $_REQUEST[$confLine] . "\"", $line );
    $cLine = false;
                }
            }

            if ( $cLine ) {
                $dbNewConfigFile[] = $line;
            }
        }

        $dbNewConfigFile = implode( $dbNewConfigFile );
// módosított config file tartalma
        var_dump( $dbNewConfigFile );
        file_put_contents( $confFilePath . ".bak", $dbNewConfigFile );

       die();
...
    }
}
7

2x?

Endyl · Már. 28. (Cs), 16.25
Nem lehetséges, hogy valamiért kétszer fut le a kérés? Elsőre lefut rendesen, utána pedig paraméterek nélkül, és ezért látod a módosítatlan tartalmat?
8

Nem hiszem... Akkor a

Theo76 · Már. 28. (Cs), 16.57
Nem hiszem... Akkor a var_dump()-nak is kétszer kellene lennie. De próbáltam úgy is, hogy magát a file elérési útját irattam ki, hogy biztos jó-e, és akkor is csak egyszer került kiírásra. Mindenesetre megvizsgálom mégegyzer...
9

1x

Theo76 · Már. 28. (Cs), 17.27
Betettem egy ellenőrző kiírást oda, ahol megvan hívva ez a rész, és csak egyszer fut le
11

Kiírás?

Endyl · Már. 28. (Cs), 21.01
Kiírás, úgy mint logolsz valahova?

Inkább nézd a webfejlesztő eszközök házózat fülét, vagy használd append módban (FILE_APPEND) a file_put_contents()-t.
14

2x

Theo76 · Már. 29. (P), 22.24
A FILE_APPEND el kijött, hogy valamiért, valahol 2szer fut le ez a kódrészlet... Szóval most jöhet a keresés, hogy hol...
18

Sikerült!

Theo76 · Már. 30. (Szo), 17.39
Nah megvan a gond... A kód az if ( !empty( $_REQUEST ) )-hez köti, hogy lefusson-e, vagy sem... Valami oknál fogva, hiába üres, akkor is lefuttatja a kódot... Igaz foggalmam sincs arról, hogy miért az első futás eredményét rakja be a file végére a FILE_APPEND utasításnál, vagy miért azzal írja felül... Ez számomra rejtély... Viszont a formba betettem egy hidden imput mezőt, és azt figyeltetve if ( isset( $_REQUEST['config'] ) ) már működik is!
19

Esetleg használsz cookie-t?

X man · Már. 30. (Szo), 18.48
Esetleg használsz cookie-t? Mert ha van, akkor tudtommal a $_REQUEST nem lehet üres.
De tévedhetek...
20

Session-t használok, de

Theo76 · Már. 31. (V), 22.25
Session-t használok, de kiírattam a $_REQUEST tartalmáz, az elvileg üres volt. De most ezzel a módszerrel már szépen teszi a dolgát... PHP-vel már voltak kalandok, pl mikor hónapokig működött egy kód, aztán elakadt. Mikor átnéztem nem értettem hogy működhetett addig. :)
21

A $_REQUEST üressége helyett

Endyl · Ápr. 1. (H), 14.59
A $_REQUEST üressége helyett én a $_SERVER['REQUEST_METHOD'] értékét vizsgálnám.

Olyat tudok elképzelni, hogy valami rewrite szabály miatt befut például egy nem megadott, automatikus favicon kérés is a php-hoz, ha olyan a routing. Tehát először érkezik a form beküldése, utána pedig a böngésző lekéri a favicont, amiben nyilván nem lesznek paraméterek, így ez felülírja a fájlt az üres változattal.
22

Kipróbáltam ezt a módszert

Theo76 · Ápr. 1. (H), 16.05
Kipróbáltam ezt a módszert is: if ( $_SERVER['REQUEST_METHOD'] === "POST" ). Jól működik ezzel is. Igen azt láttam, hogy volt egy favicon kérés, de nem gondoltam rá, hogy az képes ilyen galibára...
10

Csak a biztonság kedvéért:

X man · Már. 28. (Cs), 20.33
Csak a biztonság kedvéért: ugye lokálisan fut egy példányban, nem valami felhős szerveren vagy lokálisan, de több szálon vagy ilyesmi?
12

Saját, de virtuális gépen.

Theo76 · Már. 29. (P), 10.10
Saját, de virtuális gépen. Windows 11 Host Vmware, Ubuntu 22.04 Guest. Apache, php8.3 fpm
13

Csak annyiból volt (számomra)

X man · Már. 29. (P), 16.33
Csak annyiból volt (számomra) érdekes, hogy ha több szálon fut, akkor előfordul olyan, hogy egyik kérés az egyik szálhoz fut be, a másik a másikhoz, viszont ha a memórián/változókon nem osztoznak (tudtommal PHP nem tud ilyesmit), akkor mindegyik önálló szerverként funkcionál. És az első végrehajtja a memóriában a módosításokat, a második meg az eredeti adatokat írja vissza.
15

Ezt hogy lehet kideríteni? Az

Theo76 · Már. 30. (Szo), 07.40
Ezt hogy lehet kideríteni? Az biztos, hogy valahol duplán hajtódik végre, mert ha a FILE_APPEND-el hajtom végre a file-ba írást, akkor duplán ír. Először a jót, majd utána olyan, mintha a formtot kitöltetlenül kapná meg,ami azért furcsa mert az input mezők kitöltése kötelező a required parancs által
16

Hozzátartozik a dologhoz,

X man · Már. 30. (Szo), 10.45
Hozzátartozik a dologhoz, hogy az 5.5 óta nem láttam PHP-t.
Azt is kb. CGI szkript jelleggel futtattam, ott még nem volt ilyen gond.

Kideríteni pl. úgy lehet, hogy belépsz a virtuális gépre és kiadsz egy "ps xa | grep fpm" parancsot, ahol jó eséllyel egynél több fpm processz fog megjelenni, ami _elvileg_ azt jelenti, hogy több szálon fut az egész.
Python+gunicorn alatt biztosan úgy működik ahogy írtam: a böngésző minden kérést másik szálnak küld, de PHP+FPM esetében nem tartom lehetetlennek, hogy eleve megtartja a böngésző és a szerver közti TCP kapcsolatot és akkor az elméletem egyből hülyeséggé válik.

Az eddigiek alapján nincs sok ötletem, a teljes kódot kellene látni működés közben, viszont ahogy említettem, ezer éve nem láttam PHP-t, szóval velem nem sokra mész.
17

AZért köszönöm! :)

Theo76 · Már. 30. (Szo), 11.59
Azért nagyon köszönöm a segítségedet Neked is! :) Csak sikerül kideríteni. :)
De azért az érdekes, ha képernyőre iratom ki a változók tartalmát, akkor csak egyféle tartalom jelenik meg nem duplázódik meg, illetve maga a router kódnál, ahonnan ezt a kódot hívja meg, ott is csak egyszer hívódik meg.