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

Wie kan me hierin bijstaan?

Index.php
<!DOCTYPE html>
<html>
    <head>
		<title>Basisbestand</title>
		<link rel="stylesheet" type="text/css" href="css/style.css">    
	</head>
	
	<body>
	    <header>
		</header>
		<content>
			<?php
				try {
					//gegevens binnenhalen
					$a = fopen("bestand.ini", "r");
					$b = file("bestand.ini");
						$programmanaam = $b[0];
						$versie = $b[1];
						$hst = $b[2];
						$user = $b[3];
						$pass = $b[4];
						$db = $b[5];
					fclose($a);
				} catch (PDOException $e) {
					die("(1) DB ERROR: ". $e->getMessage());
				}
				
				//database openen
				try {
					$mysql="mysql:dbname=" . $db . ";host=" . $hst;
					echo $mysql . "<br>";
					$dbh = new PDO('$mysql', $user, $pass);
					$dbh->setAttribute( PDO::ATTR_PERSISTENT, TRUE );
					$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
				} catch (PDOException $e) {
					die("(2) DB ERROR: ". $e->getMessage());
				}
			?> 
		</content>
		<footer>
		</footer>
    </body>
</html>



Bestand.ini
Test
0.1.0.alpha.8
localhost
Test
Test
db_test

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.
Frits van Leeuwen op 15/08/2017 00:23:23

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.
Ik heb deze functie niet zelf geschreven en ooit eens gevonden ergens. Ikzelf gebruik altijd een normale config-file met constantes en variabelen.
Ja, maar, als je de tegenhangende functie niet hebt is deze functie ook zinloos. Dan kun je beter gewoon file_put_contents gebruiken.
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.

Vergeet vooral niet bij het opstellen van je DSN om een character encoding in te stellen via charset. Zoals de eerste comment op de laatstgenoemde pagina voorstelt.

Het kan (voor iedereen :p) waarschijnlijk geen kwaad om wat meer The Flipping Manual te (leren) Readen.

Reageren