Avatar billede KHHP Juniormester
22. november 2012 - 11:50 Der er 11 kommentarer og
1 løsning

Arrays og Prepared Statements

Hej
Jeg har nu arbejdet med MySQLi og Prepared Statements i et par måneder og er blevet glad for at arbejde med det. Dog savner jeg mysql_fetch_array, så jeg ville høre om jeg kan lave noget lignende i Prepared Statements?
Som eksempel kan vi jo tage eksemplet fra denne guide: http://www.eksperten.dk/guide/1480
/* Opret et prepared statement */if ($stmt = $mysqli->prepare('SELECT `fornavn`, `efternavn` FROM `tabel` WHERE `id` > ?')) {
/* Bind parametre */
$stmt->bind_param('i', $id);
/* Sæt værdier på parametrene */
$id = $_GET['id'];
/* Eksekver forespørgslen */
$stmt->execute();
/* Bind resultatet */
$stmt->bind_result($fornavn, $efternavn);
/* Hent rækker og udskriv data */
while ($stmt->fetch()) {
echo $fornavn . ' ' . $efternavn . '<br>';
}
/* Luk statement */
$stmt->close();
}
else {
/* Der er opstået en fejl */
echo 'Der opstod en fejl i erklæringen: ' . $mysqli->error;
}

I eksemplet gemmer vi jo hver enkelt værdi i sin egen variabel. Men er det muligt at gemme dem i et array i stedet, således at jeg laver et array kaldet $navn og så henter jeg blot tingene ud ved at skrive echo $navn['fornavn'].' '.$navn['efternavn']?
Jeg ved godt at det er ligemeget i en situation som eksemplet, hvor jeg kun skal hente to felter ud, men i en situation hvor jeg skal bruge 10-15 felter, så tager det jo væsentligt længere at skulle skrive variabler til alle felterne inde i bind_result() og bagefter skrive de samme navne igen når jeg skal bruge dem. Med et array skal jeg kun skrive en variabel og så kan jeg hente det jeg skal bruge ud af mig array.
Avatar billede michael_stim Ekspert
22. november 2012 - 12:51 #1
Avatar billede olebole Juniormester
22. november 2012 - 14:03 #2
<ole>

Når du har forberedt et udtryk og eksekveret det, har du to muligheder: Du kan ...

1) binde resultatet til variabler og udtrække det fra udtrykket (statement'et) med dets fetch metode.

2) oprette et result (med udtrykkets getResult metode) og bruge dets fetch metoder - f.eks. fetch_array.

mysqli::result har flere fetch metoder, men undgå såvidt muligt fetch_all, da den er temmelig grådig. Hvis du udtrækker result, skal du efterfølgende huske at frigøre hukommelsen.

Lav en favorit på denne side. Her har du en rigtig god oversigt over API'et og dets forskellige objekter/klassers metoder. Savner man et eller andet, er det somregel ganske hurtigt at skyde sig ind på - da metoderne er navngivet ret logisk  =)

/mvh
</bole>
Avatar billede olebole Juniormester
22. november 2012 - 14:05 #3
Ups ... no camels here!  :D

Metoden hedder naturligvis get_result - i bedste PHP'ish tradition  *o)
Avatar billede KHHP Juniormester
22. november 2012 - 15:21 #4
Har kigget på get_result og har forsøgt at lave noget kode der skulle hente indholdet ud.
if ($stmt = $mysqli->prepare('SELECT `titel`, `tekst` FROM `content` WHERE `page_id` = ?')) {
                    /* Bind parametre */
                    $stmt->bind_param('i', $page_id);
                    /* Eksekver forespørgslen */
                    $stmt->execute();
                    /* Bind resultatet */
                    $prepare_indhold = $stmt->get_result();
                    /*Fetch array*/
                    $indhold = $prepare_indhold->fetch_array();
                    echo $indhold['tekst'];
                    $stmt->close();
                }

Resultatet bliver en blank side, fra det punkt hvor jeg anvender det. Har sat echo ind efter hvert punkt i mit prepared statement, for at finde ud af hvornår det går galt. Det viste sig at den stopper lige efter $stmt->execute(); og aldrig kommer til $prepare_indhold = $stmt->get_result();
Hvis den var kommet forbi det punkt så havde den skrevet Array prepared og dette sker ikke.
Har kigget under mysqli_stmt::get_result har forsøgt at indsætte foreach-loop for at se om det gav noget, men det ændrede intet. Men et loop burde ikke være nødvendigt, da mit statement, i den sammenhæng jeg benytter den, kun skal hente ét sæt data ud.
Hvor er det lige det går galt?
Avatar billede olebole Juniormester
22. november 2012 - 15:45 #5
RTFM  *o)

"Det viste sig at den stopper lige efter $stmt->execute(); og aldrig kommer til $prepare_indhold = $stmt->get_result();"

For det første tror jeg ikke på, scriptet ikke når længere - og desuden kan jeg ikke se, du prøver at echo'e noget lige efter.

Hvis du ikke medsender et argument, vil fetch_array hente et talindekseret array. Men du får vel en besked fra PHP, der siger, at du benytter en ikke eksisterende array key i dit eksempel. Ellers bør du se på din PHP-opsætning
Avatar billede olebole Juniormester
22. november 2012 - 15:48 #6
PS: "Hvis du udtrækker result, skal du efterfølgende huske at frigøre hukommelsen."


                    /*Fetch array*/
                    $indhold = $prepare_indhold->fetch_array();
                    echo $indhold[0];
                    $prepare_indhold->free();
                    $stmt->close();
Avatar billede KHHP Juniormester
22. november 2012 - 18:56 #7
Hovsa, ja min fejl. Havde kopieret min kode inden jeg satte echo ind. Glemte at kopiere en gang til. Har nu rettet lidt på tingene og har nu et script der ser således ud:
if ($stmt = $mysqli->prepare('SELECT `titel`, `tekst` FROM `content` WHERE `page_id` = ?')) {
                    /* Bind parametre */
                    $stmt->bind_param('i', $page_id);
                    $page_id = 1;
                    echo 'bind_param<br />';
                    /* Eksekver forespørgslen */
                    $stmt->execute();
                    echo 'execute<br />';
                    /* Bind resultatet */
                    $prepare_indhold = $stmt->get_result();
                    echo 'prepare array<br />';
                    /*Fetch array*/
                    $indhold = $prepare_indhold->fetch_array();
                    echo $indhold[0];
                    $prepare_indhold->free();
                    echo 'free mem<br />';
                    $stmt->close();
                }
                else {
                    $_SESSION['fail'] = 'Der opstod en fejl i erklæringen: ' . $mysqli->error;
                }

har forsøgt på en helt ren side uden andet end ovenstående og den når stadig kun til echo 'execute'.. Der forekommer ingen yderligere fejl. Screenshot: http://gratisupload.dk/vis_billede/687670/
Avatar billede olebole Juniormester
22. november 2012 - 21:35 #8
Har du prøvet at echo'e $mysqli->error før og efter eksekveringen?
Avatar billede KHHP Juniormester
23. november 2012 - 13:37 #9
Har nu forsøgt at udskrive $mysqli->error både før og efter execute().
if ($stmt = $mysqli->prepare('SELECT `titel`, `tekst` FROM `content` WHERE `page_id` = ?')) {
                    /* Bind parametre */
                    $stmt->bind_param('i', $page_id);
                    $page_id = 2;
                    echo 'bind_param<br />'.$mysqli->error.'<br />';
                    /* Eksekver forespørgslen */
                    $stmt->execute();
                    echo 'execute<br />'.$mysqli->error.'<br />';
                    /* Bind resultatet */
                    $prepare_indhold = $stmt->get_result();
                    echo 'prepare array<br />'.$mysqli->error.'<br />';
                    /*Fetch array*/
                    $indhold = $prepare_indhold->fetch_array();
                    echo $indhold[0];
                    $prepare_indhold->free();
                    echo 'free mem<br />'.$mysqli->error.'<br />';
                    $stmt->close();
                }
                else {
                    $_SESSION['fail'] = 'Der opstod en fejl i erklæringen: ' . $mysqli->error;
                }

Der forekommer ingen fejl undervejs. Den gør det samme som på screenshot fra tidligere.
Avatar billede olebole Juniormester
23. november 2012 - 17:52 #10
Nu har jeg testet din kode og kan ikke fremkalde fejl. Jeg har testet med denne tabel:

CREATE TABLE IF NOT EXISTS `content` (
  `page_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `titel` varchar(50) COLLATE utf8_danish_ci NOT NULL,
  `tekst` varchar(50) COLLATE utf8_danish_ci NOT NULL,
  PRIMARY KEY (`page_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci;

INSERT INTO `content` (`page_id`, `titel`, `tekst`) VALUES
    (1, 'titel 1', 'tekst 1'),
    (2, 'titel 2', 'tekst 2'),
    (3, 'titel 3', 'tekst 3'),
    (4, 'titel 4', 'tekst 4');

- og denne kode:

if ($stmt = $mysqli->prepare('SELECT `titel`, `tekst` FROM `content` WHERE `page_id` = ?')) {
    /* Bind parametre */
    $stmt->bind_param('i', $page_id);
    $page_id = 2;
   
    /* Eksekver forespørgslen */
    $stmt->execute();
   
    /* Bind resultatet */
    $prepare_indhold = $stmt->get_result();
   
    /*Fetch array*/
    $indhold = $prepare_indhold->fetch_array();
    echo $indhold[0];
    $prepare_indhold->free();
   
    $stmt->close();
} else {
    echo $mysqli->error;
}

... works like a charm!  =)
Avatar billede KHHP Juniormester
23. november 2012 - 23:15 #11
Ja, så er der nok et eller andet galt med min opsætning.
Har nu taget en testfil fra localhost og lagt den op på mit webhotel og her får jeg en fejl der også er nævnt i den php-dokumentation du linkede(og som jeg har bookmarked) til og den ser således ud:
Fatal error: Call to undefined method mysqli_stmt::get_result() in /home/khanseni/public_html/span.php on line 44
Omtalte linje 44 er: $prepare_indhold = $stmt->get_result();
Ifølge php-dokumentationen skulle det være noget med at den funktion jeg gerne vil bruge ikke er slået til/installeret på serveren. Den nævner dog intet om hvad jeg skal kigge efter min phpinfo(). Jeg er så heldig at jeg kan indsætte en php.ini med ændringer der kun skal gælde for min side og derved kan jeg slå funktionen til, såfremt den er installeret. I localhost kan jeg blot rette det til. Men hvad skal jeg kigge efter for at tjekke om arrays til mysqli er installeret?
Avatar billede KHHP Juniormester
23. januar 2013 - 19:49 #12
Lukker og slukker. Tråden har været død meget længe
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester



IT-JOB

Udviklings- og Forenklingsstyrelsen

Alsidig testmanager til udvikling af vigtige IT-systemer

Aller Leisure A/S

Erfaren .NET-udvikler

Capgemini Danmark A/S

Salesforce CTO - Nordics

Udviklings- og Forenklingsstyrelsen

Engageret platformsejer med flair for it-drift

Metro Service A/S

Risk & Cyber Security Expert