Her får du hjelp til å lage hjemmeside med video. Alle verktøy og programmer vi bruker til å lage webside er gratis.
Hvordan kjøre SQL query mot MySQL database med PHP
Hvordan bruker/programmerer man PHP for å kjøre SQL spørringer mot MySQL database?
Jeg vil bruke PHP til å hente ut informasjon fra MySQL databasen ved hjelp av SQL queries.
Deler av denne guiden i hvordan man bruker PHP til å hente ut data fra MySQL har sammenheng med hvordan man oppretter tabeller og database i MySQL. I tråden det linkes til oppretter vi data som vi skal hente ut i denne guiden.
Koble til MySQL med PHP via db-access.php
For å kjøre query mot MySQL med PHP må man først og fremst opprette en tilkobling til MySQL. Nedenfor er et kodeeksempel på hvordan man kan koble til databasen.
Men før vi ser på scriptet, vil jeg komme med en anbefaling: Jeg anbefaler de som skal opprette en tilkobling til MySQL med PHP til å opprette et eget PHP-script som gjør dette, for så å legge det utenfor webrooten, og så bruke PHP-funksjonen:
<?php
require('/bane/til/db-access.php');
?>for å hente inn tilkoblingen til MySQL i skript som trenger tilgang til MySQL.
På den måten kan man skifte ut brukernavn, passord og databasenavn i én fil, og dermed vil den endrede påloggingsinformasjonen gjelde for samtlige skript som trenger tilgang til MySQL.
db-access.php
Filen tar seg av tilkoblingen til MySQL, og kan se slik ut:
<?php
// Host til MySQL
$db_host = 'localhost';
// Databasenavn i MySQL
$db_name = 'ditt_databasenavn';
// MySQL bruker
$db_user = 'ditt_brukernavn';
// MySQL passord
$db_pass = 'ditt_passord';
// Kobler til MySQL
$db_connection = mysql_connect($db_host, $db_user, $db_pass);
/**
Setter karaktersettet til utf8 for tilkoblingen.
Dette kan gi problemer, så i visse tilfeller kan
det være nødvendig å fjerne denne innstillingen.
**/
mysql_set_charset('utf8', $db_connection);
// Velger database i MySQL
mysql_select_db($db_name, $db_connection);
?>Du bytter selvsagt ut detaljene i scriptet med dine personlige databaseinnstillinger.
Kjør en testspørring
For at vi skal kunne kjøre en testspørring, forutsettes det at du har noe å kjøre spørringer på. Her forutsettes det, som nevnt innledningsvis, at du har lagt inn noen data i MySQL.
Det første vi gjør er å opprette en ny PHP-fil. La oss kalle den query.php
.
query.php
<?php
// Henter inn db-access.php
require('/bane/til/db-access.php');
// Lager en spørring
$query = 'SELECT * FROM user_table';
// Kjører query (spørring)
$result = mysql_query($query, $db_connection);
// Looper gjennom resultatene
while ($data = mysql_fetch_assoc($result)) {
print 'BrukerID: ' . $data['user_id'] . '<br />';
print 'Navn: ' . $data['user_name'] . '<br />';
print 'Epost: ' . $data['user_email'] . '<br />';
print '<hr />';
}
?>Hvis du har gjort det riktig, og kjører filen query.php
skal du nå få ut samtlige brukere du har lagret i databasen.
Legg merke til at $data er en assosiativ array, og at nøklene i arrayen er navnet på feltene i tabellen. Dette er fordi vi bruker PHP-funksjonen mysql_fetch_assoc() til å hente ut data fra MySQL.
Her kan du laste ned PHP scriptet som henter data fra MySQL-databasen og endre db-access.php
for å passe ditt oppsett.
Det neste blir å kombinere forms for å kjøre spørringer med forskjellige kriterier.
- Siden du har BlueHost, så er databasehosten localhost.
- Det er fordi du ikke bruker riktig PATH (filbane) når forsøker å hente inn filen ved hjelp av require-funksjonen i PHP. For eksemplets skyld: Prøv å legg begge filene i én (og samme) katalog og bruk require-funksjonen på denne måten for å hente den inn:
<?php
require('db-access.php');
?>Bra, da lager vi et form. Opprett et HTML-dokument med navnet index.html
og putt følgende form i det:
<form id="query" name="query" method="post" action="query.php">
<fieldset>
<legend>Hent brukerdata</legend>
<label for="user_id">BrukerID:
<input type="text" name="user_id" id="user_id" />
</label>
<input type="submit" value="Sjekk bruker" />
</fieldset>
</form>Bytt så ut alt innholdet i query.php
med:
<?php
if($_POST) {
// Henter inn db-access.php
require('db-access.php');
// Lager en spørring
$query = sprintf(
'SELECT * FROM user_table WHERE user_id = \'%s\'',
mysql_real_escape_string($_POST['user_id']));
// Kjører query (spørring)
$result = mysql_query($query, $db_connection) or die(mysql_error());
// Looper gjennom resultatene
while ($data = mysql_fetch_assoc($result)) {
print 'BrukerID: ' . $data['user_id'] . '<br />';
print 'Navn: ' . $data['user_name'] . '<br />';
print 'Epost: ' . $data['user_email'] . '<br />';
print '<hr />';
}
}
?>Last opp alt dette på webhotellet ditt, gå til index.html
og forsøk å skrive inn en av brukerIDene.
Vi bruker sprintf() og mysql_real_escape_string() for å sikre oss mot SQL injections. Man bør validere brukerinput ytterligere, men for eksemplets skyld holder dette.
Ser du noen sammenhenger? Klarer du å opprette ett felt til i HTML og kjøre SQL-spørringen på flere kriterier fra brukeren?
Er ikke rart det da, du er både tolmodig og dyktig mannebiss! :)
Nei, akkurat den der er vrien, er mye å holde styr på. Legg merke til hvordan jeg gjør denne. Har indentert litt for å gjøre det tydeligere.
<?php
$query = sprintf
(
'SELECT * FROM user_table
WHERE user_id = \'%s\'
AND user_name = \'%s\'',
mysql_real_escape_string($_POST['user_id']),
mysql_real_escape_string($_POST['user_name'])
);
?>Grunnen til at jeg har slashene
foran fnuttene
, er fordi jeg escaper dem.
Da klarer du kanskje å legge til et tredje kriterie?
Med funksjonen springf() rundt queryen kan man sette inn verdier etter stringen. Basert på hva slags specifier
(f.eks %s) vil springf() behandle data forskjellig.
<?php
$string = sprintf
(
'Jeg heter \'%s\'',
'Hjemmeside'
);
print $string;
// Jeg heter 'Hjemmeside'
?>Denne vil erstatte %s (string) med Hjemmeside
. Man kan bruke forskjellige specifiers
, se mer om sprintf i PHP manualen.
mysql_real_escape_string() er en funksjon som escaper diverse for å unngå såkale MySQL injections (en måte å hacke databaser ved å endre spørringen ved hjelp av brukerinput, enten i URL, form eller ved å sende POST til serveren). Også denne funksjonen kan du lese om i PHP manualen.
Hvis du ikke er komfortabel nok til å sette deg inn i akkurat dette enda, så er det viktig å få med seg at disse øker sikkerheten i skripet ditt.
Jepp, det stemmer. Man kan også bruke OR (hvis man mener ELLER og ikke OG, slik man gjør med AND), men det skal du jo ikke gjøre i dette tilfellet.
Det går også ann å joine tables. Dvs hente ut informasjon fra to eller flere tables og kombinere data fra dem i resultatene fra MySQL. I de fleste store databaser er det mange relasjoner mellom forskjellige tabeller. Hvis du vil lære litt om det, så er det bare å spørre ved en annen anledning.
Tenk f.eks. på nettby eller facebook. Hvis A er venn med B der, så er A og B to brukere, registrert i samme database tabell. Videre er det en relasjonstabell som sier hvilke brukerIDer som er venner med hvem.
Anyways, du er vel klar for dette scriptet ditt du nå? Du får poppe tilbake i den tråden hvis du har noen flere spørsmål rundt akkurat det. Mulig den neste tråden din vil handle om sessions, hehe. Trøtt som ei strømpe her, men er ikke kvelden riktig enda.
Klart jeg kan det, hehe. Det spiller jo egentlig ingen rolle hvilke data du har funnet, så lenge du har funnet dem. Hvis det er samsvar mellom det brukeren plottet inn i formet og det som kommer tilbake, så har man én row
med data.
For å se til at dette er tilfellet kan man gjøre det slik:
<?php
// Antall resultater er 1
if(mysql_num_rows($result) == 1) {
print '<p>Inne</p>';
// Finner ikke resultat
} else {
print '<p>Error</p>';
}
?>Legg merke til at jeg bruker $result her. Det funksjonen mysql_num_rows() gjør, er å returnere en integer (et heltall) som naturlig nok er antall rader i resultatet.
Her har jeg modifisert query.php
litt, slik at du kanskje bedre ser sammenhengene.
<?php
// Sjekker at det blir postet
if($_POST) {
// Henter inn db-access.php
require('db-access.php');
// Lager en spørring
$query = sprintf(
'SELECT * FROM user_table WHERE user_id = \'%s\'',
mysql_real_escape_string($_POST['user_id']));
// Kjører query (spørring)
$result = mysql_query($query, $db_connection) or die(mysql_error());
// Sjekker om det er resultater
if(mysql_num_rows($result) == 1) {
// Looper gjennom resultatene
while ($data = mysql_fetch_assoc($result)) {
print 'BrukerID: ' . $data['user_id'] . '<br />';
print 'Navn: ' . $data['user_name'] . '<br />';
print 'Epost: ' . $data['user_email'] . '<br />';
print '<hr />';
}
// Finner ikke 1 resultat
} else {
print '<p>ERROR ERROR ERROR</p>';
}
// Ble ikke postet
} else {
print '<p>Error: Ingenting er postet.</p>';
}
?>Eksemplene i denne tråden er enkle modeller
, man sjekker gjerne mye mer nøysomt om brukerdata er tuklet med osv. Sikkerhet er viktig når man programmerer.
En god idé er å skille HTML, CSS og PHP fra hverandre i mest mulig grad. Ikke slik som her at vi har en salig blanding.
Det enkle svaret er nei, det lange svaret er ja.
Først: Grunnen til at man ønsker å legge "db-access.php" utenfor public_html, er fordi filene i denne katalogen er tilgjengelig fra world wide web. Hvis noe skulle gå galt på webserveren, f.eks. at PHP-dokumenter ikke tolkes, men sendes til nettleseren i klartekst, så vil brukeren som akkesserer dokumentet se hva det inneholder.
Fjerne mulighet for tilgang med .htaccess
Dette kan riktignok begrenses ved å sette opp en regel i .htaccess, slik:
<files db-access.php>
order deny,allow
deny from all
</files>Merk at .htaccess
må ligge i samme katalog som db-access.php
i dette tilfellet. Bruk filbane hvis .htaccess
ligger under db-access.php
i filtreet (hvilket den må gjøre for å ha effekt.
Kryptering av passord
Ved å legge "db-access.php" utenfor public_html, vil den aldri være tilgjengelig fra world wide web.
For å kryptere passordet, må man først kryptere det, så lagre det i kryptert form, så lage en funksjon som dekrypterer passordet. Funksjonen bør ligge i en egen fil, også utenfor public_html, slik at en potensiell hacker ikke har tilgang til den.
Som du ser blir dette en redundant løsning, gitt løsningen jeg skisserte med å legge selve "db-access.php" utenfor public_html, eller begrense tilgangen til den med .htaccess.
Nei, det trenger den ikke, den inneholder jo ingen konfedensielle data.
Poenget med å legge ting utenfor webrooten, er at man ikke skal ha tilgang til disse dokumentene fra world wide web via webserveren.
PHP har derimot mulighet for å hente inn ressurser som ligger utenfor webrooten. PHP er jo ikke webserveren, og PHP må ikke brukes i forbindelse med nettsider. Man kan også lage andre ting ved hjelp av PHP, f.eks. skript som utfører vedlikeholdsoppgaver i Linux (men til det ville jeg heller brukt shell scripts though).
Det du er ute etter å gjøre er mao. å lage et table for output fra PHP. Her bruker jeg eksemplet ovenfor og bygger videre på dette.
<?php
// Kjører query (spørring)
$result = mysql_query($query, $db_connection) or die(mysql_error());
// Sjekker om det er resultater
if(mysql_num_rows($result) == 1) {
// Bygger opp table
$output = '<table id="brukere">';
$output .= '<thead><tr>';
$output .= '<th>BrukerID</th>';
$output .= '<th>Navn</th>';
$output .= '<th>Epost</th>';
$output .= '</tr></thead>';
$output .= '<tbody>';
// Looper gjennom resultatene
while ($data = mysql_fetch_assoc($result)) {
// Legger brukere inn i table
$output .= '<tr>';
$output .= '<td>' . $data['user_id'] . '</td>';
$output .= '<td>' . $data['user_name'] . '</td>';
$output .= '<td>' . $data['user_email'] . '</td>';
$output .= '</tr>';
}
// Avslutter table
$output .= '</tbody>';
$output .= '<tfoot></tfoot>';
$output .= '</table>';
// Skriver ut table
print $output;
}
?>Legg merke til at vi starter variabelen $output med følgende notasjon:
<?php
$output = 'Første data i variabel';
?>For så å bruke punktum foran likhetstegnet etterpå, slik:
<?php
$output .= 'Mer informasjon i variabel';
?>På denne måten overskriver vi ikke gammel data i variabelen, men legger ny data til. Avslutningsvis printer vi hele variabelen og alt innholdet i den til skjermen.
For å style tabellen bruker du naturligvis CSS.

med hilsen
Thomas Kile