Door
Frits van Leeuwen
op 14-08-2017 21:08
gewijzigd op 14-08-2017 21:16
8.422 views
Hallo allemaal,
Ik kom er niet uit. Ik zoek al een hele tijd, maar het wordt me niet duidelijk.
Ik heb in een installatie een database "db_test" laten maken met een user "Test" (ww="Test") en het tekst bestand.ini. In bestand.ini staat alle informatie die nodig is voor het vervolg. Ik heb het gecheckt en dat klopt allemaal.
Bij het openen/starten van "Index.php", haal ik de uit "bestand.ini" binnen, en ik geef ze aan variabelen. Dan wil ik de database activeren en het aantal records tellen dat in de tabel [tabel_administratires] staat. Aan dit laatste durf ik niet goed te beginnen, omdat ik deze melding krijg:
mysql:dbname=db_test ;host=localhost
(2) DB ERROR: invalid data source name
Ik heb mijn code er al een beetje op voorbereid. Ik gebruik nu $b[x] waarbij x natuurlijk een nummer is.
Ik gebruik dat i.p.v. de variabele die allemaal een eigen naam kregen.
Ik ken parse_ini_file nog niet. Ik zal eerst moeten kijken hoe ik het kan inpassen. Maar als je een tip hebt... ik hou me aanbevolen. Ik denk zeker dat het waardevol is.
[php]parse_ini_file[/php] leest *echt* INI bestanden, niet iets zoals je nu gebruikt. Het werkt gegarandeerd een stuk beter, dat is een ding dat zeker is. Feit blijft dat je dit soort bestanden beter buiten je webroot kan plaatsen, omdat iedereen er nu gewoon bij zou kunnen.
Nu heb je een structuur waar niemand wijs uit wordt. Want wat is Test op lijn 5? De username, password? Servernaam?
Test
0.1.0.alpha.8
localhost
Test
Test
db_test
Als je met *echte* ini-bestanden werkt, dan heb je meteen een key en een value, en je kan ze ook nog eens onderverdelen in secties, wat niet ten koste gaat aan je functie die je gebruikt.
[algemene instellingen]
programmanaam = Test
versie = 0.1.0.alpha.8
[connectie]
host = localhost
user = Test
pass = Test
database = db_test
En natuurlijk, zoals eerder gezegd, dit ini-bestand BUITEN de webroot plaatsen.
Op dit moment werkt het programma op mijn thuisnetwerk. (Of eigenlijk werkt het er nog niet ;-) ) Maar dat is de eerste situatie. Ik heb een plekje toegewezen waar ik een web-based programa wil bouwen. Hiermee hoop ik ook gelijk PHP te leren schrijven. Dat dan wel met PDO.
De opbouw van mijn bestand is nu nog heel klein. Maar dat is misschien ook een goed moment om de structuur gelijk goed neer te zetten.
Wouw wat heb ik een hoop geleerd vanavond. Heel erg bedankt. Ik ga het maken van mijn ini-bestand wijzigen. En dan ga ik dit voorbeeld over nemen.
Is daar ook zo'n functie voor? Of moet ik dat op de manier doen zoals ik die eerder liet zien?
Voor nu heb ik even genoeg achter de computer gezeten. Morgen zal ik waarschijnlijk wel weer verder gaan.
Dus slaap lekker allemaal en tot de volgende keer.
Ik zou vandaag de dag sowieso niet meer met fopen en consorten werken als het niet strict noodzakelijk is. Voor het snel lezen en schrijven van bestanden hebben we [php]file_get_contents[/php] en [php]file_put_contents[/php]. Of, als je de inhoud van een bestand per regel in een array wil hebben: [php]file[/php]. Uiteraard niet vergeten te trimmen per regel, wat waarschijnlijk nu ook je probleem is.
Ik ga het maken van mijn ini-bestand wijzigen. En dan ga ik dit voorbeeld over nemen.
Is daar ook zo'n functie voor? Of moet ik dat op de manier doen zoals ik die eerder liet zien?
Met deze functie:
function write_php_ini($array, $file)
{
$res = array();
foreach($array as $key => $val)
{
if(is_array($val))
{
$res[] = "[$key]";
foreach($val as $skey => $sval) $res[] = "$skey = ".(is_numeric($sval) ? $sval : '"'.$sval.'"');
}
else $res[] = "$key = ".(is_numeric($val) ? $val : '"'.$val.'"');
}
safefilerewrite($file, implode("\r\n", $res));
}
function safefilerewrite($fileName, $dataToSave)
{ if ($fp = fopen($fileName, 'w'))
{
$startTime = microtime(TRUE);
do
{ $canWrite = flock($fp, LOCK_EX);
// If lock not obtained sleep for 0 - 100 milliseconds, to avoid collision and CPU load
if(!$canWrite) usleep(round(rand(0, 100)*1000));
} while ((!$canWrite)and((microtime(TRUE)-$startTime) < 5));
//file was locked so now we can store information
if ($canWrite)
{ fwrite($fp, $dataToSave);
flock($fp, LOCK_UN);
}
fclose($fp);
}
}
Je stopt er een array in, dus vergelijkbaar is met de output van parse_ini_file. Commentaarregels worden hierin wel genegeerd. Maar dat heb je toch niet nodig als je geautomatiseerd de ini-file aanpast.
Waar is je "safefileread" functie dan die een shared lock pakt, die je nodig zal hebben om safefilewrite nuttig te laten zijn? Locking zal anders doodleuk genegeerd worden.
Los hiervan, het werken met handmatig geformatteerde bestanden is toch een beetje voortborduren op een minder slimme ontwerpbeslissing.
Toen ik de manual raadpleegde of er misschien een makkelijker alternatief was kwam ik meteen in de eerste user comment al een voorbeeld tegen met .ini file.
Daarnaast lijkt het ook mogelijk om via een alias rechtstreeks een DSN-string (Data Source Name) uit een .ini file te lezen, zonder allerlei gecompliceerde bestandsoperaties. Waarschijnlijk moet je dan wel definiëren wat geldige paden voor .ini bestanden zijn en dat ding dan op de goede plaats zetten uiteraard.