Avatar billede BTEngineer Novice
10. februar 2012 - 12:35 Der er 59 kommentarer og
1 løsning

Brug af session og sikkerhed

Hej Eksperter.

Jeg har lavet et login system, hvor jeg benytter mig af sessions.

Når brugeren logger ind, gøres det på følgende måde:

<?php
session_start();

$_SESSION[email]     = $_POST[email];
$_SESSION[kodeord]     = $_POST[kodeord];
?>

Selvfølgelig tester jeg om email/kodeord passer sammen. Men ellers bliver $_SESSION startet således.

Når brugeren er logget ind, er det standard at øverste og nedreste del er opbygget således:

<?php
session_start();
if(isset($_SESSION['email']) AND isset($_SESSION['kodeord'])) {

indhold bla bla..

} else {
echo "Du er ikke logget ind.";
}
?>

Mit spørgsmål er om det er sikkert nok?

Søgte lidt rundt omkring, og stødte så på:
http://phpsec.org/projects/guide/4.html

Som fortæller noget om sikkerhed i forhold til brug af sessions.

Hvad ville være bedst? Og hvordan skal det laves?

Jeg har sørget for at sikre mod al sql-injection ved brug af mysql_real_escape_string(); når der arbejdes med $_GET[].

Jeg tænkte at man kunne lave en session.php-fil hvor al den kode der som standard skal sørge for at det er sikkert, kan inkluderes på alle sider i login systemet.

Jeg håber der er nogen der kan gøre mig lidt klogere, og være med til at gøre det sikkert! :-)

// Henrik
Avatar billede The_Buzz Novice
10. februar 2012 - 12:45 #1
Hej Henrik

Hvis det du har lavet der, ikke er sikkert nok - er 80+% af de hjemmesider jeg har set i koden på ikke sikre nok.

Du kan ikke som bruger direkte manipulere session's på serveren - med mindre du har root access.

Du kan jo kombinere det med IP check (når man logger ind sættes der et ip nummer i database), der så checkes sammen med andre "sessions fra brugeren" - så man inden for f.eks. 5 minutter ikke kan access siden fra en anden IP end den man loggede på med sidst.

Derudover - kan du gemme en cookie på brugerens computer - som f.eks. består af:

$dinegensalt = '9034rsdvn ,mdfknk2324kn m,34kl2n43ln2l43';
$cookie_to_add = sha1($_SESSION['email'] . $_SESSION['kodeord'] . $dinegensalt);

og så checke om han har den cookie sat f.eks. hver tredie side han prøver at tilgå.
Avatar billede BTEngineer Novice
10. februar 2012 - 13:18 #2
Hej The_Buzz

Tak for dit svar :-)

Det var selvfølgelig også nogle gode idéer! Men jeg tænkte på f.eks. om funktionerne:

session_regenerate_id();

session_id();

(som oplyses i kode-forslagene på det link jeg skrev i det første indlæg)

Og så videre, kunne drage nogen nytte. Jeg er ikke klar over hvordan de bruges i praksis.

Det er i sær i forbindelse med persondataloven, og selvfølelig brugernes troværdighed til mit site, at det er vigtigt, at de personlige oplysninger er lagret sikkert i databasen, og ikke bare kan nuppes uden problemer. Det skal de ikke kunne! :-) Direkte hacking til databasen/serveren vil nok ikke være muligt. Surftown som jeg er hostet ved, er så vidt jeg ved, meget sikker!
Avatar billede The_Buzz Novice
10. februar 2012 - 13:45 #3
Hej dounie

Du kan eventuelt læse lidt på det:
http://php.net/manual/en/function.session-regenerate-id.php

Ikke at jeg tror, det betyder forfærdeligt meget med folks session. Den side du angiver siger jo også selv at PHP's session ID generator er meget random, og derfor er det super svært at ville gætte et id

Det er jo ikke fortløbende numre session består af - det er jo en virkelig lang string.

http://test.modified.dk/session.php

<?php
session_start();

$old_sessionid = session_id();

session_regenerate_id();

$new_sessionid = session_id();

echo "Old Session: $old_sessionid<br />";
echo "New Session: $new_sessionid<br />";

print_r($_SESSION);
?>
Avatar billede olebole Juniormester
10. februar 2012 - 14:32 #4
<ole>

"Jeg har sørget for at sikre mod al sql-injection ved brug af mysql_real_escape_string();" >> Det er ikke en særlig sikker fremgangsmåde.

I stedet for at bruge det efterhånden forældede mysql-API, bør du kikke på prepared statements i mysqli. Det er langt sikrere - og i tilgift væsentligt hurtigere.

/mvh
</bole>
Avatar billede BTEngineer Novice
11. februar 2012 - 00:22 #5
Tak for det The_Buzz, det vil jeg tage et kig på!

Tak for det olebole :-). Men jeg kan ikke sådan lige gå til objektorienteret programmering, på 0,5.. Det kræver at man sætter sig virkelig ind i det!

Jeg kan ikke se hvad der er galt med mysql_real_escape_string(); - funktionen sørger for at tegn som '," osv. bliver fjernet var strengen.

Når jeg laver en forbindelse til databasen er det:

$hent = mysql_query("SELECT * FROM mintabel ORDER BY id DESC") or die(mysql_error());
$vis = while(mysql_fetch_array($hent)) {
echo $vis['blabla'];
}

Sådan gør jeg det normalt. Skal jeg opdatere noget i mysql, gør jeg således:

mysql_query("UPDATE mintabel SET bla='mereblabla' WHERE id='$_GET[id]'") or die(mysql_error());

Eksempelvis. Her vil jeg så, hvis det er "offentligt" for alle brugere, sørge for at bruge mysql_real_escape_string(); til id'et, da det er noget de jo evt. kan ændre på i linket på siden.

Det ville være rart at få at vide om det er helt ude i skoven, eller om det er ok :-)
Avatar billede olebole Juniormester
11. februar 2012 - 00:47 #6
Ingen taler om, at du skal bruge mysqli objektorienteret. Hvis du bruger mere end et halvt minut på at kikke på de to links, vil du se, at API'et kan bruges både OO og proceduralt. Desuden er det pærelet at bruge det OO - og ingen siger, at du behøver at OO'e resten af din kode. Her er en tutorial, som er meget let at gå til. Prøv at kikke på den og se, hvor let det er, selvom der er brugt mysqli OO.

Det er muligt, at du ikke kan se, hvad der er galt med det gamle API. Det kan såmænd også fungere - på samme måde som tabellayout og HTML3.2 uden CSS stadig er anvendeligt.

Ikke desto mindre er det ikke uden grund, at man har konstrueret et kraftigt forbedret API (mysqli = mysql - improved), og at ingen professionelle løsninger idag bliver skrevet i det gamle API. Mysqli er både langt sikrere og væsentligt hurtigere.

Mysql har altid været anset for 'mindre lødig' i forhold til 'de store' såsom mssql og oracle - ikke mindst p.gr.a. manglen på parametriserede kald og deraf dårligere sikkerhed.

Den tid er endelig forbi, men om man så vil fortsætte med at 'fedte rundt' med det gamle API, er naturligvis ens eget valg.

Ja, din update er skoleeksemplet på rent selvmord! Du hjælper den, der vil tømme din DB så effektivt, som det overhovedet kan gøres.

Specielt når man ikke kan overskue, hvad man gør, bør man lade databasen om selv at escape, hvad der skal escapes - og det kan du tydeligvis ikke  =)
Avatar billede olebole Juniormester
11. februar 2012 - 00:55 #7
Din update kræver, at du helt 100% sikkert husker at bruge mysql_real_escape_string. Det viser al erfaring for det første, at du ikke gør - og *BANG*, så er du død!

Desuden er DB'ens egen escaping mere effektiv - og du undgår de uheldige sideeffekter, din fremgangsmåde ellers byder på. The_Buzz og jeg har således lige været forbi en af dem tidligere i dag.
Avatar billede BTEngineer Novice
11. februar 2012 - 11:48 #8
Tak for det. Jeg har læst tutorialen, og fået det til at fungere i en opret_bruger.php fil, således:

if ($opret_bruger = $mysqli->prepare("INSERT INTO brugere (email, kodeord, aktivkode) values (?, ?, ?)")) {
   
    /* Binder parametrene */
    $opret_bruger->bind_param('sss', $email, $cryptpass, $aktiveringskode);
    // s=String, d=decimal, i=Integer, b=blob (sent in packets)
   
    /* Udfører: prepared Statement */
    $opret_bruger->execute();
   
  /* Lukker: the statement */
    $opret_bruger->close();   

} else {
    /* Fejl */
    printf("Der opstod en fejl i Prepared Statement: %s\n", $mysqli->error);


Jeg har ikke helt fået fat i, hvad s,d,i,b skal gøre. Jeg skrev først ssd, da aktiveringslinket jo er tal. Men så fik jeg et helt andet tal, end det der var i strengen. Men det virker nu med 'sss'.

Ser det ellers rigtigt ud? Og er det samme princip med update, select m.m?

Ellers kan jeg godt se fidusen i det.

Jeg er godt klar over, at med en ubehandlet $_GET[] ind i en mysql_query vil være at skyde sig selv i foden - jeg ved ikke hvordan du i teorien vil kunne tømme databasen i min update.. - Men hvis den først får mysql_real_escape_string(); f.eks. sådan her:

$id = mysql_real_escape_string($_GET[id]);
mysql_query("UPDATE mintabel SET bla='mereblabla' WHERE id='$id'") or die(mysql_error());

Så er den vel forholdsvis sikker? Men jeg kan stadigvæk godt se det smarte ved Prepared Statements.
Avatar billede BTEngineer Novice
11. februar 2012 - 11:57 #9
En lidt anden ting. Jeg kan hurtigt komme til at lave mange mysql_query SELECT og UPDATE i en fil. I slutningen af filen skriver jeg mysql_close(); og går ud fra at alle forbindelserne er lukkede. Er det en fejlantagelse?

Hvis jeg samtidigt skal opdatere noget i flere database, så gør jeg det blot:

mysql_query("UPDATE tabel_a SET bla = 'blablab'") or die(mysql_error());

mysql_query("UPDATE tabel_b SET bla = 'blabla'") or die(mysql_error());

mysql_query("UPDATE tabel_c SET bla = 'blabla'") or die(mysql_error());

Og så videre.. Er det også besværligt gjort?

Vil høre om der er et bedre alternativ.
Avatar billede BTEngineer Novice
11. februar 2012 - 14:01 #10
Jeg har prøvet at hente mine data med prepared statements. Men det fungerer ikke.

Min kode:
$load = mysql_query("SELECT * FROM * WHERE email = '$_SESSION[email]'") or die(mysql_error());
$show = mysql_fetch_array($load);

TIL:

/* Create the prepared statement */
if ($stmt = $mysqli->prepare("SELECT FirstName,LastName FROM CodeCall ORDER BY LastName")) {   
    /* Execute the prepared Statement */
    $stmt->execute();
   
    /* Bind results to variables */
    $stmt->bind_result($firstName, $lastName);
   
    /* fetch values */
    while ($stmt->fetch()) {
        printf("%s %s\n", $lastName, $firstName);
    }

    /* Close the statement */
    $stmt->close();
   
}
else {
    /* Error */
    printf("Prepared Statement Error: %s\n", $mysqli->error);
}

Mine koder kommer godt nok til at fylde meget mere på den måde. Men hvis det er sikkert er det vel det værd!! :-)

Jeg skal ikke have lavet en while() på den her, så hvordan får jeg den til at lave et array i stedet $show[]... Det skal jeg bruge flere gange i mit script nemlig..

Beklager de mange spørgsmål! :-)
Avatar billede olebole Juniormester
11. februar 2012 - 20:22 #11
Lad os lige tage én ting ad gangen (over flere indlæg) - og det tyder ikke på, du endnu har forstået, hvad fordelene er ved prepared statements (herefter kaldet PS) eller, hvad bagdelene er ved mysql_real_escape_string.

Med den sidste får du problemer med legale apostroffer - f.eks. bliver Tim O'Reilly til Tim O\'Reilly. Ligesom PHP i mange tilfælde i forvejen escaper med backslashes - med deraf dobbelt escaping tilfølge.

Derudover er du ikke beskyttet mod SQL-injection ved multibyte tegnsæt - bortset fra utf-8. Din løsning er altså ikke særlig portabel. Da du ydermere kun anvender den på strenge, står du jo stadig pivåben for injections ved talfelter.

Derudover viser al erfaring, at du med garanti glemmer mysql_real_escape_string på et tidspunkt - på et sted og tidspunkt, hvor det har katastrofale konsekvenser.

mysql_real_escape_string beskytter dig derfor somme tider - andre gange gør den ikke! Lidt som at spille Lotto ... eller måske nærmere: Russisk roulette!  *o)

Det gamle API bygger på, at du 'hækler' strenge sammen til et SQL-kald, som sendes til DB'en. Det er i udgangspunktet en potentielt farlig og elendig løsning.

Med PS kommer dine variabler aldrig i nærheden af et SQL-udtryk. Dit statement opbygger en procedure, som gemmes i DB'en, og når du efterfølgende sender variabler som parametre til denne procedure, indgår de ikke i en SQL-streng. Proceduren afgør, om parametren passer med det forventede og escaper den i forhold til det af DB'en benyttede tegnsæt. Parametren kan indeholde, hvad somhelst. Er det andet end det forventede, forkastes kaldet bare.

Alt dette friholder dig naturligvis ikke for at tjekke alt, hvad der ankommer 'udefra'. Alt, hvad du ikke selv har skrevet, skal tjekkes for, om det præcist svarer til, hvad du forventer. I den forbindelse nytter det ikke noget, du whiner over at skulle skrive flere linjer kode. Ja, gu' fylder det, men det handler ikke om udviklerens niveau af dovenskab - det handler om hans kundes og dennes brugeres sikkerhed  *o)
Avatar billede olebole Juniormester
11. februar 2012 - 20:33 #12
Vedr. #8:

Feltets datatype afgør, om du skal bruge s, i, d eller b - ikke, hvilke tegn variablen/parametren indeholder. Skal værdien "123.456" indsættes i et VARCHAR felt, skal du således bruge s, uagtet det ligner et tal.

"Jeg er godt klar over, at med en ubehandlet $_GET[] ind i en mysql_query vil være at skyde sig selv i foden" >> Både og! Du skal som sagt altid tjekke, om variablen stemmer præcist med, hvad du forventer at modtage. Den er til gengæld ikke til fare i injection sammenhæng. Derfor skal du ikke bruge nogen form for escaping af dén grund.

- og skal olebole have brygget lidt kaffe. Resten følger  =)
Avatar billede olebole Juniormester
11. februar 2012 - 20:47 #13
Vedr. #9:

Nu roder du mysql og mysqli sammen. $opret_bruger->close(); lukker dit statement. Din forbindelse $mysqli er stadig åben.

Skal du opdatere, opretter du et passende mysqli-statement og eksekverer det. Da du ikke kan binde tabelnavnet til en parameter, må du oprette og lukke et statement til hver update. Du kan gøre det med et komplekst statement - men lad være med at koncentrere dig om det nu. Du har rigeligt at se til i øjeblikket  *o)
Avatar billede olebole Juniormester
11. februar 2012 - 21:04 #14
Vedr. #10:

Den knap så elegante måde ser sådan ud:

/* Create the prepared statement */
if ($stmt = $mysqli->prepare("SELECT FirstName,LastName FROM CodeCall ORDER BY LastName")) {   
    /* Execute the prepared Statement */
    $stmt->execute();
   
    /* Bind results to variables */
    $stmt->bind_result($firstName, $lastName);
   
    /* Create array to hold the recordset */
    $rows = array();
   
    /* fetch values */
    while ($stmt->fetch()) {
        $rows[] = array('firstName'=>$firstName, 'lastName'=>$lastName);
    }

    /* Close the statement */
    $stmt->close();
   
}
else {
    /* Error */
    printf("Prepared Statement Error: %s\n", $mysqli->error);
}


Man kan bruge en lidt fiksere fremgangsmåde ved brug af klassen ReflectionMethod og dennes invokeArgs metode, men det er lidt mere kompliceret, da det kræver, at man har godt styr på at sende argumenter 'by reference'.

Glem det på nuværende tidspunkt og koncentrer dig om at lære det grundlæggende - og blive godt dus med dét. Så kan du altid udvikle dine kompetencer og lave lidt mere elegante løsninger  =)
Avatar billede olebole Juniormester
11. februar 2012 - 21:11 #15
PS: Nu, vi taler sikkerhed, bør du - når koden går live - slette dine printf's af fejl. Du bør også søge for, at PHP's fejlmeddelelser fra - eller sætte dem ned til et minimum. Evt. ved at bruge error_reporting i en includefil i toppen af hvert dokument. Her kan du så skifte mellem alle eller ingen/få meddelelser alt efter, om du er i udvikling eller ej.

Du kan også sætte det i php.ini, hvis du adgang til den.

Det var så sidste indlæg i denne omgang, men du stiller bare uddybende spørgsmål, hvis du har nogen  =)
Avatar billede BTEngineer Novice
12. februar 2012 - 13:51 #16
Mange tak for de, som altid, fyldestgørende svar! :-)

Jeg har fået det til at virke med INSERT og SELECT.
For at forstå hvordan man undgår sql-injections, m.m. så bør man vel vide hvordan de laves? Har du et link el. lign. som bare fortæller lidt om det? ( Ikke fordi jeg er ude på at rydde nogen database :-P )

Min UPDATE, kommer ikke med fejl, men databasen registrere heller ingenting.

$fornavn = htmlspecialchars($_POST[fnavn]);
$efternavn = htmlspecialchars($_POST[enavn]);
$adresse = htmlspecialchars($_POST[adresse]);
$postnr = htmlspecialchars($_POST[postnr]);
$city = htmlspecialchars($_POST[city]);
$tlf = htmlspecialchars($_POST[tlf]);
$bank = htmlspecialchars($_POST[bank]);
$regnr = htmlspecialchars($_POST[regnr]);
$konto = htmlspecialchars($_POST[kontonr]);

$fornavn = mysql_real_escape_string($fornavn);
$efternavn = mysql_real_escape_string($efternavn);
$adresse = mysql_real_escape_string($adresse);
$postnr = mysql_real_escape_string($postnr);
$city = mysql_real_escape_string($city);
$tlf = mysql_real_escape_string($tlf);
$bank = mysql_real_escape_string($bank);
$regnr = mysql_real_escape_string($regnr);
$konto = mysql_real_escape_string($konto);

//
// Mysql_real_escape_string er vel ikke længere nødvendigt? :-)
// Hvad med htmlspecialchars(); ?

$opdater_bruger = $mysqli->prepare("UPDATE brugere SET fnavn=?, enavn=?, adresse=?, postnr=?, city=?, tlf=?, bank=?, regnr=?, kontonr=?, dag=?, maaned=?, aar=?, profil_godkendt=? WHERE id=?");
   
/* Binder parametrene */
$opdater_bruger->bind_param('ssssssssssssss', $fnavn, $enavn, $adresse, $postnr, $city, $tlf, $bank, $regnr, $kontonr, $dag_v, $maaned_v, $aar_v, 'nej', $id);
   
    /* Udfører: prepared Statement */
    $opdater_bruger->execute();
   
  /* Lukker: the statement */
$opdater_bruger->close();

mysql_close($mysqli); // Lukker forbindelse: $mysqli

Har du nogen idé om hvad der er galt? (har du sikkert). Hvordan laver man desuden en DELETE-query? Når dette er løst, så tror jeg at det kommer til at spille =)
Avatar billede olebole Juniormester
12. februar 2012 - 16:39 #17
<ole>

mysql_real_escape_string hjælper dig ikke med noget. htmlspecialchars kan være yderst fornuftig, men ved tal nøjes du med at tjekke, om der er tale om et tal - eller type'er variablen med (int). I det hele taget skal du som sagt tjekke variablerne for, om de indeholder, hvad du forventer.

Jeg tvivler på, du skal bruge s til alle dine parametre, Prøv:

/* Binder parametrene */
$opdater_bruger->bind_param('ssssssssssssss', $fnavn, $enavn, $adresse, $postnr, $city, $tlf, $bank, $regnr, $kontonr, $dag_v, $maaned_v, $aar_v, 'nej', $id);

if ($opdater_bruger->errno) echo $opdater_bruger->error.'<br>';

Du kan se et DELETE statement i eksemplet her, hvor du også kan lære at finde antallet af berørte rækker  =)

/mvh
</bole>
Avatar billede BTEngineer Novice
12. februar 2012 - 22:53 #18
Okay tak :-)

Der sker ingenting med tilføjelse af ovenstående kode.

Alle mine felter i databasen er lavet med varchar, hvilket jeg har forstået, skal være [b]s[b].
Avatar billede BTEngineer Novice
12. februar 2012 - 22:53 #19
[b][s/b], sådan :-P
Avatar billede BTEngineer Novice
12. februar 2012 - 22:54 #20
Jeg prøver lige én gang til.. s
Avatar billede olebole Juniormester
12. februar 2012 - 23:27 #21
- og du har sat error_reporting(E_ALL) i toppen af dokumentet?
Avatar billede olebole Juniormester
12. februar 2012 - 23:33 #22
Måske, du vil få en fejl med 'error linjen', hvis du flytter den ned efter din execute. I hvertfald skal jeg lede meget længe i din kode for atfinde de variabler, du bruger i:

/* Binder parametrene */
$opdater_bruger->bind_param('ssssssssssssss', $fnavn, $enavn, $adresse, $postnr, $city, $tlf, $bank, $regnr, $kontonr, $dag_v, $maaned_v, $aar_v, 'nej', $id);

Kan du finde dem alle? Næppe ...!  *o)
Avatar billede olebole Juniormester
12. februar 2012 - 23:34 #23
$fnavn, $enavn? Og der er flere  =)
Avatar billede BTEngineer Novice
12. februar 2012 - 23:44 #24
Jeg kan ikke få nogen fejlmeddelelse frem.

Min kode ser nu således ud:

$fnavn = htmlspecialchars($_POST[fnavn]);
$enavn = htmlspecialchars($_POST[enavn]);
$adresse = htmlspecialchars($_POST[adresse]);
$postnr = htmlspecialchars($_POST[postnr]);
$city = htmlspecialchars($_POST[city]);
$tlf = htmlspecialchars($_POST[tlf]);
$bank = htmlspecialchars($_POST[bank]);
$regnr = htmlspecialchars($_POST[regnr]);
$konto = htmlspecialchars($_POST[kontonr]);

if(!$dag || $maaned || $aar) { // Sørger for at man ikke bare trykker "Opdater profil"
    $dag_v = $_POST['fods_dag'];                                // .. således at datoen bare ændres "", dvs. ingenting
    $maaned_v = $_POST['fods_maaned'];                        // .. det medfører at fødselsdagsfelterne kommer frem igen.
    $aar_v = $_POST['fods_aar'];
}
if($dag || $maaned || $aar) {
    $dag_v = $dag;
    $maaned_v = $maaned;
    $aar_v = $aar;
}

$opdater_bruger = $mysqli->prepare("UPDATE brugere SET fnavn=?, enavn=?, adresse=?, postnr=?, city=?, tlf=?, bank=?, regnr=?, kontonr=?, dag=?, maaned=?, aar=?, profil_godkendt=? WHERE id=?");

    /* Binder parametrene */
$opdater_bruger->bind_param('sssssssssssssi', $fnavn, $enavn, $adresse, $postnr, $city, $tlf, $bank, $regnr, $konto, $dag_v, $maaned_v, $aar_v, 'nej', $id);

if ($opdater_bruger->errno) echo $opdater_bruger->error.'<br>';
    // s=String, d=decimal, i=Integer, b=blob (sent in packets) - afhænger af om det varchar (s), decimal (d) osv. i databasen!
   
    /* Udfører: prepared Statement */
    $opdater_bruger->execute();
   
  /* Lukker: the statement */
$opdater_bruger->close();
mysql_close($mysqli); // Lukker forbindelse fra $mysqli->prepare

Der var rigtig nok nogle variabler der ikke passede sammen med ovenstående som er behandlet med htmlspecialchars().. Men det skulle gerne være rettet nu. Derudover har jeg ændret den sidste til i, fordi ID'et jo er int()-format i databasen.

Er vi på rette vej? =)
Avatar billede olebole Juniormester
12. februar 2012 - 23:53 #25
$id?  =)

Prøv at sætte disse to linjer ind:

$opdater_bruger = $mysqli->prepare("UPDATE brugere SET fnavn=?, enavn=?, adresse=?, postnr=?, city=?, tlf=?, bank=?, regnr=?, kontonr=?, dag=?, maaned=?, aar=?, profil_godkendt=? WHERE id=?");

$myTest = array($fnavn, $enavn, $adresse, $postnr, $city, $tlf, $bank, $regnr, $konto, $dag_v, $maaned_v, $aar_v, 'nej', $id);
var_dump($myTest);

    /* Binder parametrene */
$opdater_bruger->bind_param('sssssssssssssi', $fnavn, $enavn, $adresse, $postnr, $city, $tlf, $bank, $regnr, $konto, $dag_v, $maaned_v, $aar_v, 'nej', $id);

- og så luk din forbindelse med:

$mysqli->close();


PS: Du har vel oprettet en forbindelse, ikk'?. I koden synes $mysqli at opstå på magisk vis. Den sætter du forhåbentlig højere oppe i koden
Avatar billede olebole Juniormester
12. februar 2012 - 23:56 #26
Med det sidste mener jeg noget i stil med:

$mysqli = new mysqli("myHost", "username", "password", "myDB");
Avatar billede BTEngineer Novice
13. februar 2012 - 00:09 #27
Jeg har lavet en forbindelse i min cfg-fil, som er inkluderet i toppen af filen. :-)

Har lavet forbindelse således:
// Prepared Statements Connection..

$mysqli = new mysqli("XXXX", "XXXXX", "XXXXX", "XXXX");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

array(14) { [0]=> string(6) "Henrik" [1]=> string(7) "xxxx" [2]=> string(13) "xxxx" [3]=> string(4) "xxxx" [4]=> string(11) "xxxx" [5]=> string(8) "xxxx" [6]=> string(10) "xxxx" [7]=> string(4) "xxxx" [8]=> string(9) "xxxx" [9]=> string(1) "xxxx" [10]=> string(2) "xxxx" [11]=> string(4) "xxxx" [12]=> string(3) "nej" [13]=> int(1) }

Dette er hvad der kommer ud nu. Har erstattet noget af det med xxxx. :)
Avatar billede olebole Juniormester
13. februar 2012 - 00:36 #28
Hmmm ... det lyder som en ikke helt ny PHP-version - hvis du altså bruger error_reporting(E_ALL); i toppen. Du burde få en fejl.

Læg mærke til, at element #13 i array'et $myTest ikke har nogen værdi. Mon ikke det er fordi, $id ikke er sat?  =)
Avatar billede olebole Juniormester
13. februar 2012 - 00:36 #29
Derfor skrev jeg første linje i #25  *o)
Avatar billede BTEngineer Novice
13. februar 2012 - 00:46 #30
Jeg har sat error_reporting(E_ALL); helt i toppen af filen.

Jeg har hentet informationer fra databasen, hvor id'et meget gerne skulle være sat:


/* Create the prepared statement */

if ($stmt = $mysqli->prepare("SELECT id, fnavn, enavn, adresse, postnr, city, tlf, aar, maaned, dag, bank, regnr, kontonr, profil_godkendt, retbonus FROM brugere WHERE email = '$_SESSION[email]'")) {   
    /* Execute the prepared Statement */
   
    $stmt->execute();
   
$stmt->bind_result($id, $fnavn, $enavn, $adresse, $postnr, $city, $tlf, $aar, $maaned, $dag, $bank, $regnr, $kontonr, $profil_godkendt, $retbonus);
   
    /* Create array to hold the recordset */
    $rows = array();
   
    /* fetch values */
    while ($stmt->fetch()) {
        $rows[] = array('id'=>$id, 'fnavn'=>$fnavn, 'enavn'=>$enavn, 'adresse'=>$adresse, 'postnr'=>$postnr, 'city'=>$city, 'tlf'=>$tlf, 'aar'=>$aar, 'maaned'=>$maaned, 'dag'=>$dag, 'bank'=>$bank, 'regnr'=>$regnr, 'kontonr'=>$kontonr, 'profil_godkendt'=>$profil_godkendt, 'retbonus'=>$retbonus);
    }
   
    /* Close the statement */
    $stmt->close();
 
      $mysqli->close();
} else {
    /* Error */
    printf("Prepared Statement Error: %s\n", $mysqli->error);
}
Avatar billede olebole Juniormester
13. februar 2012 - 02:16 #31
Ja, men din UPDATE kan tydeligvis ikke finde den. Ligger de to kald i hver sin funktion? I så fald er varibler jo lokale.

Din SELECT lægger rækkerne i array'et $rows, så den ligger typisk som $rows[n]['id'] (hvor n er et tal). Jeg kender dog ikke strukturen i din kode, så jeg ved ikke, om din UPDATE kan 'se' $rows.

PS: Husk i øvrigt altid at bruge apostroffer i array kald, når indekset er en streng. Ikke $_POST[fnavn], men $_POST['fnavn'] - Array do's and don'ts
Avatar billede BTEngineer Novice
13. februar 2012 - 02:59 #32
Okay, jeg kan ikke selv få det til at fungere pt.

Nu får du lige hele molevitten:

<?
error_reporting(E_ALL);

session_start();
if(isset($_SESSION['email']) AND isset($_SESSION['kodeord'])) {

include("konfiguration/cfg.php");

/* Create the prepared statement */

if ($stmt = $mysqli->prepare("SELECT id, fnavn, enavn, adresse, postnr, city, tlf, aar, maaned, dag, bank, regnr, kontonr, profil_godkendt, retbonus FROM brugere WHERE email = '$_SESSION[email]'")) {   
    /* Execute the prepared Statement */
   
    $stmt->execute();
   
$stmt->bind_result($id, $fnavn, $enavn, $adresse, $postnr, $city, $tlf, $aar, $maaned, $dag, $bank, $regnr, $kontonr, $profil_godkendt, $retbonus);
   
    /* Create array to hold the recordset */
    $rows = array();
   
    /* fetch values */
    while ($stmt->fetch()) {
        $rows[] = array('id'=>$id, 'fnavn'=>$fnavn, 'enavn'=>$enavn, 'adresse'=>$adresse, 'postnr'=>$postnr, 'city'=>$city, 'tlf'=>$tlf, 'aar'=>$aar, 'maaned'=>$maaned, 'dag'=>$dag, 'bank'=>$bank, 'regnr'=>$regnr, 'kontonr'=>$kontonr, 'profil_godkendt'=>$profil_godkendt, 'retbonus'=>$retbonus);
    }
   
    /* Close the statement */
    $stmt->close();
 
      $mysqli->close();
} else {
    /* Error */
    printf("Prepared Statement Error: %s\n", $mysqli->error);
}



function birthday ($birthday){
    list($aar,$maaned,$dag) = explode("-",$birthday);
    $year_diff  = date("Y") - $aar;
    $month_diff = date("m") - $maaned;
    $day_diff  = date("d") - $dag;
    if ($day_diff < 0 || $month_diff < 0)
      $year_diff--;
    return $year_diff;
}

if(isset($_POST['opdater'])) {

if(!$_POST[fnavn] || !$_POST[enavn] || !$_POST[adresse] || !$_POST[postnr] || !$_POST[city] || !$_POST[tlf] || !$_POST[bank] || !$_POST[regnr] || !$_POST[kontonr]) {
    $fejl[] = "Alle felter skal udfyldes!";
}

if($_POST[tlf] < "8") {
    $fejl[] = "Telefon nummeret er ugyldigt!";
}

if($fejl) {
    echo "<div id='fejl'>";
    echo "<font color='black'><b>Der opstod følgende fejl:</b></font><br />";
for($i=0;
sizeof($fejl) > $i;
$i++) {
    echo("<li><font color='RED'>$fejl[$i]</font></li>");
}
    echo "</div><br />";
} else {

$fnavn = htmlspecialchars($_POST[fnavn]);
$enavn = htmlspecialchars($_POST[enavn]);
$adresse = htmlspecialchars($_POST[adresse]);
$postnr = htmlspecialchars($_POST[postnr]);
$city = htmlspecialchars($_POST[city]);
$tlf = htmlspecialchars($_POST[tlf]);
$bank = htmlspecialchars($_POST[bank]);
$regnr = htmlspecialchars($_POST[regnr]);
$konto = htmlspecialchars($_POST[kontonr]);

if(!$dag || $maaned || $aar) {
    $dag_v = $_POST['fods_dag'];               
    $maaned_v = $_POST['fods_maaned'];               
    $aar_v = $_POST['fods_aar'];
}
if($dag || $maaned || $aar) {
    $dag_v = $dag;
    $maaned_v = $maaned;
    $aar_v = $aar;
}

$opdater_bruger = $mysqli->prepare("UPDATE brugere SET fnavn=?, enavn=?, adresse=?, postnr=?, city=?, tlf=?, bank=?, regnr=?, kontonr=?, dag=?, maaned=?, aar=?, profil_godkendt=? WHERE id=?");

$myTest = array($fnavn, $enavn, $adresse, $postnr, $city, $tlf, $bank, $regnr, $konto, $dag_v, $maaned_v, $aar_v, 'nej', $id);
var_dump($myTest);

    /* Binder parametrene */
$opdater_bruger->bind_param('sssssssssssssi', $fnavn, $enavn, $adresse, $postnr, $city, $tlf, $bank, $regnr, $konto, $dag_v, $maaned_v, $aar_v, 'nej', $id);

   
    /* Udfører: prepared Statement */
    $opdater_bruger->execute();
   
  /* Lukker: the statement */
$opdater_bruger->close();
mysql_close($mysqli); // Lukker forbindelse fra $mysqli->prepare
     
echo "<div id='check'>";
echo "<b>Din profil er nu opdateret</b><br /><a href='/brugere/udbetal'>klik her</a>";
echo "</div>";


}
}

if(!isset($_POST['opdater']) OR $fejl) {
?>


<div id="ret_profil_wrapper">
<h1>Opdater profil</h1>

<div class="information">
<?
if($profil_godkendt == "nej") {
echo "Din konto er under godkendelse, vent venligst på en godkendelse!";
} else {
?>
<?php
if($retbonus == "ja") {
echo "..;
} else {

}
?>
</div>

<br>

<h2>Kontakt oplysninger</h2>
<hr>
<p>Hvis du ønsker at få rettet din email adresse, <a href="/kontakt">kontakt os da venligst.</a></p><br>

<div id="ret_profil">
<form action="/brugere/ret_profil" method="post">
<label>*Fornavn</label>
<input type="text" name="fnavn" id="fnavn" value="<?php if($fejl) { echo $_POST['fnavn']; } else { echo $fnavn; } ?>">

<label>*Efternavn</label>
<input type="text" name="enavn" id="enavn" value="<?php if($fejl) { echo $_POST['enavn']; } else { echo $enavn; } ?>">

<label>*Adresse</label>
<input type="text" name="adresse" id="adresse" value="<?php if($fejl) { echo $_POST['adresse']; } else { echo $adresse; } ?>">

<label>*Post nr. </label>
<input type="text" name="postnr" id="postnr" value="<?php if($fejl) { echo $_POST['postnr']; } else { echo $postnr; } ?>">

<label>*By</label>
<input type="text" name="city" id="city" value="<?php if($fejl) { echo $_POST['city']; } else { echo $city; } ?>">

<label>*Tlf </label>
<input type="text" name="tlf" id="tlf" value="<?php if($fejl) { echo $_POST['tlf']; } else { echo $tlf; } ?>" maxlength="15"><br>


<label>*Fødselsdag</label>

<?php
if($dag AND $maaned AND $aar != "") {
$alder = birthday("$aar-$maaned-$dag");

    echo "<p class='birthday-tekst'>Vi har allerede registreret at du er $alder år gammel, og at din fødselsdagsdato er $dag/$maaned-$aar :-)</p><br><br>";
       
} else {

?>
    <select name="fods_dag">
        <? for($i = 1; $i <= 31; $i++) : ?>
            <option value="<?=$i;?>"><?=$i;?></option>
        <? endfor; ?>
    </select>
    <select name="fods_maaned">
        <option value='1'>Januar</option>
        <option value='2'>Februar</option>
        <option value='3'>Marts</option>
        <option value='4'>April</option>
        <option value='5'>Maj</option>
        <option value='6'>Juni</option>
        <option value='7'>Juli</option>
        <option value='8'>August</option>
        <option value='9'>September</option>
        <option value='10'>Oktober</option>
        <option value='11'>November</option>
        <option value='12'>December</option>
    </select>

    <select name="fods_aar">
        <? $aar_nu = date('Y'); $aar_nu_17 = $aar_nu-17; for($i = 1940; $i <= $aar_nu_17; $i++) : ?>
            <option value="<?=$i;?>"><?=$i;?></option>
        <? endfor; ?>
    </select>
<? } ?>

<div class="clear"></div>

<br>

<h2>Bank oplysninger</h2>
<hr>
<p>Det er meget vigtigt at dine bankoplysninger er indtastet korrekt.</p><br>

<label>*Bank </label>
<input type="text" name="bank" value="<?php if($fejl) { echo $_POST['bank']; } else { echo $bank; } ?>"><br>

<label>*Reg nr.</label>
<input type="text" name="regnr" value="<?php if($fejl) { echo $_POST['regnr']; } else { echo $regnr; } ?>"><br>

<label>*Konto nummer </label>
<input type="text" name="kontonr" value="<?php if($fejl) { echo $_POST['kontonr']; } else { echo $kontonr; } ?>">

<br><br>
<input type="submit" value=" " class="opdater" name="opdater">

</form>
</div>

</div>

<?
}
}

} else {
    include("brugere/ikke_logget_ind.php");
}
?>
Avatar billede BTEngineer Novice
13. februar 2012 - 03:02 #33
Så lige en besked fra dig og svarede - men nu er de væk? :o)
Avatar billede BTEngineer Novice
13. februar 2012 - 03:03 #34
Der var de. Ved ikke lige hvad der skete :-)
Avatar billede BTEngineer Novice
13. februar 2012 - 21:34 #35
Jeg har testet om ID'et bliver hentet ved $id, fra min rows[], og det gør den.

Jeg kan ikke se hvad problemet er. :-/
Avatar billede BTEngineer Novice
14. februar 2012 - 00:32 #36
Jeg fandt fejlen!

Fejlen var, at jeg havde lukket $mysqli forbindelse tidligere i scriptet, hvor jeg hentede mine data:

$mysqli->close();

Nu har jeg placeret det i bunden af scriptet, er dette ikke okay? Den lukker vel forbindelsen? :-)

Tusinde mange gange tak for hjælpen :-)
Avatar billede olebole Juniormester
14. februar 2012 - 12:24 #37
Jeg har ikke haft tid til at kikke på tråden før nu. Ja, det lukker forbindelsen, hvilket selvfølgelig var årsagen til problemet. Godt, du fandt det  =)

#33 >> Eksperten går i knæ hver nat omkring kl. 2-3 stykker. Af uforståelige årsager er det åbenbart ikke muligt at holde applikationen kørende uden en større, natlig opdatering af databaser. Derfor opstår der ofte mærkelige ting med forsvindende inlæg i nattens løb  :o|
Avatar billede BTEngineer Novice
14. februar 2012 - 12:58 #38
Det er bare helt i orden. :-)

Nå forsøren, det lyder jo helt skræmmende! :o

Well, jeg lader indlægget her være åbent lidt i nu, hvis jeg nu lige skulle komme i tanke om et spørgsmål eller to, de næste par dage, okay? :-)
Avatar billede BTEngineer Novice
16. februar 2012 - 18:02 #39
Så fik jeg et lille problem mere.

Jeg har nogle variabler som skal sættes ind, selvom de er ligmed 0. Når værdien er 0, er det som om at den ikke vil sætte dem ind. Det virker fint med det gamle mysql_query(insert into blabla....), men det virker altså ikke med prepared statements, så kan du måske sige mig hvad løsningen er?

if($_GET[pniearning] == NULL) {
    $orderamount = insert_null_val;
    } else {
    $orderamount = $_GET[pniearning];
    }
   
    if($_GET['pnicpid'] == NULL) {
    $cpid = insert_null_val;
    } else {
    $cpid = $_GET[pnicpid];
    }

$pni = $_GET[pni];
$type = $_GET[pnitype];

$dato = date('d/m-Y');
$tid = date('H:i');
$ip = $_SERVER[REMOTE_ADDR];
                                                                                       
if ($nyt_lead = $mysqli->prepare("INSERT INTO new_check (`orderamount`, `cpid`, `pni`, `type`, `partner`, `dato`, `tid`, `ip`) values (?, ?, ?, ?, ?, ?, ?, ?)")) {
   
    /* Binder parametrene */
    $nyt_lead->bind_param('ssssssss', $orderamount, $cpid, $pni, $type, iqmedier, $dato, $tid, $ip);
    // s=String, d=decimal, i=Integer, b=blob (sent in packets)
   

    /* Udfører: prepared Statement */
    $nyt_lead->execute();
   
  /* Lukker: the statement */
    $nyt_lead->close(); 

   
  //$mysqli->close(); // Lukker forbindelsen til databasen!
}

Jeg har prøvet følgende, men det giver blot en blank side.

Værdierne orderamount og cpid kan være ligmed 0. Ellers hvis de har en værdi, skal den selvfølgelig indsættes i stedet.
Avatar billede olebole Juniormester
16. februar 2012 - 18:14 #40
Er det ikke bare:

if($_GET['pniearning'] == 0) {
    $orderamount = insert_null_val;
} else {
    $orderamount = $_GET['pniearning'];
}

if($_GET['pnicpid'] == 0) {
    $cpid = insert_null_val;
} else {
    $cpid = $_GET['pnicpid'];
}

- og husk så de gåseøjne ved array kald! Se sidst i #31  *o)
Avatar billede BTEngineer Novice
16. februar 2012 - 18:27 #41
Nej det virker ikke :(

Den viser stadigvæk en blank side - og ingenting i databasen.

Ja, skal nok huske dem. Men hvad gør det? :-)
Avatar billede olebole Juniormester
16. februar 2012 - 18:37 #42
"Ja, skal nok huske dem. Men hvad gør det?" >> Klik på linket i slutningen af #31  =)

Hvis ikke, det virker, er jeg ikke sikker på, jeg forstår problemet. Hvad får du ud af at tilføje lidt linjer:

    $test = array($orderamount, $cpid, $pni, $type, iqmedier, $dato, $tid, $ip);
    var_dump($test);
    /* Binder parametrene */
    $nyt_lead->bind_param('ssssssss', $orderamount, $cpid, $pni, $type, iqmedier, $dato, $tid, $ip);
    // s=String, d=decimal, i=Integer, b=blob (sent in packets)
    echo $nyt_lead->error;
Avatar billede BTEngineer Novice
16. februar 2012 - 18:46 #43
&#65279;array(8) { [0]=> string(15) "insert_null_val" [1]=> string(15) "insert_null_val" [2]=> string(5) "15654" [3]=> NULL [4]=> string(8) "blabla" [5]=> string(10) "16/02-2012" [6]=> string(5) "18:45" [7]=> string(13) "xxxxxx" }

Får følgende fejl.
Avatar billede olebole Juniormester
16. februar 2012 - 19:04 #44
Hmmmm ... måske er det din NULL-værdi i $type(?) Prøv lige at echo'e en evt. fejl efter din execute:

    /* Udfører: prepared Statement */
    $nyt_lead->execute();
    echo $nyt_lead->error;
Avatar billede BTEngineer Novice
16. februar 2012 - 20:48 #45
Får nøjagtig samme fejl :/
Avatar billede olebole Juniormester
16. februar 2012 - 21:34 #46
Betyder "samme fejl": Ingen fejl?
Avatar billede BTEngineer Novice
16. februar 2012 - 22:02 #47
&#65279;array(8) { [0]=> string(15) "insert_null_val" [1]=> string(15) "insert_null_val" [2]=> string(5) "15654" [3]=> NULL [4]=> string(8) "xxxx" [5]=> string(10) "16/02-2012" [6]=> string(5) "21:32" [7]=> string(13) "xxxx" }

Den her fejl.
Avatar billede olebole Juniormester
16. februar 2012 - 22:47 #48
Jeg ser ingen fejl ...? Hvad udskriver dette:

    /* Udfører: prepared Statement */
    $nyt_lead->execute();
    echo $nyt_lead->error;
Avatar billede BTEngineer Novice
17. februar 2012 - 12:24 #49
Nej, undskyld, det er selvfølgelig ingen fejl. Men det du kom med, ændrede så vidt jeg kan se ikke noget:

array(8) { [0]=> string(15) "insert_null_val" [1]=> string(15) "insert_null_val" [2]=> string(2) "16" [3]=> NULL [4]=> string(8) "xxxxxx" [5]=> string(10) "17/02-2012" [6]=> string(5) "12:23" [7]=> string(13) "xxxxxxxx" }

Koden ser således ud nu:

include("mysql.php");

if($_GET[pni] == NULL) {
echo "Fejl";
} else {

   
if($_GET['pniearning'] == 0) {
    $orderamount = insert_null_val;
} else {
    $orderamount = $_GET['pniearning'];
}

if($_GET['pnicpid'] == 0) {
    $cpid = insert_null_val;
} else {
    $cpid = $_GET['pnicpid'];
}

$pni = $_GET[pni];
$type = $_GET[pnitype];

$dato = date('d/m-Y');
$tid = date('H:i');
$ip = $_SERVER[REMOTE_ADDR];
                                                                                       
if ($nyt_lead = $mysqli->prepare("INSERT INTO new_check (`orderamount`, `cpid`, `pni`, `type`, `partner`, `dato`, `tid`, `ip`) values (?, ?, ?, ?, ?, ?, ?, ?)")) {
   
    $test = array($orderamount, $cpid, $pni, $type, iqmedier, $dato, $tid, $ip);
    var_dump($test);

    $nyt_lead->bind_param('ssssssss', $orderamount, $cpid, $pni, $type, iqmedier, $dato, $tid, $ip);
 
    $nyt_lead->execute();

    echo $nyt_lead->error;
       
    $nyt_lead->close();
Avatar billede olebole Juniormester
17. februar 2012 - 16:07 #50
De to linjer

    $test = array($orderamount, $cpid, $pni, $type, iqmedier, $dato, $tid, $ip);
    var_dump($test);

Er kun en test for at vise, hvad du indsætter. Resultatet, som de udskriver, viser, at din variabel $type er NULL. Prøv at sætte den til et eller andet 'foo' eller 'bla' eller whatever. Og prøv så, om der indsættes noget
Avatar billede BTEngineer Novice
18. februar 2012 - 00:20 #51
Ja, og nu udskriver den disse data:

array(8) { [0]=> string(15) "insert_null_val" [1]=> string(15) "insert_null_val" [2]=> string(3) "140" [3]=> string(15) "insert_null_val" [4]=> string(8) "xxxxxx" [5]=> string(10) "18/02-2012" [6]=> string(5) "00:15" [7]=> string(12) "xxxxxx" }

Jeg lavede det bare ligesom ved de andre to, med en insert_null_val, hvis der ingenting er. Jeg har også prøvet at sætte den ligmed blabla, men det bliver stadigvæk ikke sat ind i databasen - og jeg har prøvet at sætte dem alle lig blabla (alle dem der er sat til insert_null_vall).
Avatar billede olebole Juniormester
18. februar 2012 - 15:42 #52
I det udskrevne array, har du rettet det fjerde elements værdi til 'xxxxxx'. Men det undrer mig, fordi variablen hedder iqmedier i din binding:

$nyt_lead->bind_param('ssssssss', $orderamount, $cpid, $pni, $type, iqmedier, $dato, $tid, $ip);

- og i din udskrivning af variabler:

$test = array($orderamount, $cpid, $pni, $type, iqmedier, $dato, $tid, $ip);
var_dump($test);

Hvis der er tale om en variabel, så savner jeg et $ - og det er jeg ret sikker på, PHP også gør. Der kan dog også være tale om en defineret konstant, men dem plejer man jo at skrive med stort.

Hvad er der tale om?
Avatar billede BTEngineer Novice
18. februar 2012 - 15:49 #53
Det klart. Det virker nu hvor jeg sætter det i en variabel i stedet for. Jeg var bare ret sikker på at det var okay at sætte det en som ren tekst.

Tak for hjælpen igen, igen, igen...! :-)
Avatar billede olebole Juniormester
18. februar 2012 - 16:25 #54
Selvtak. Du kan godt skrive klartekst ind, men så skal det i gåseøjne:

$nyt_lead->bind_param('ssssssss', $orderamount, $cpid, $pni, $type, 'iqmedier', $dato, $tid, $ip);


Det undrer mig nu også lidt, at f.eks. feltet orderamount er af typen VARCHAR. Brug de datatyper, der passer til det, felterne skal indeholde - og angiv kun den længde, de skal indeholde. Skal du indsætte et fornavn, er det spild af plads at afsætte mulighed for at indsætte 255 tegn. Det er nok sjældent at skulle håndtere navne som Herbert Ludwig Leopold Maximillian van der Schwandvogel III  *o)
Avatar billede BTEngineer Novice
19. februar 2012 - 19:31 #55
Jeg har forsøgt at gøre det med gåseøjne, men det virker ikke. Det virker først når det bliver sat ind via. en variabel.

Ja, jeg skal bestemt have kigget lidt på databasen, tak :-)

Der er en ting der undre mig lidt. Når jeg laver en while:
while($hent_data->fetch()) {
$vis_data[] = array('pointprivat'=>$pointprivat, 'type'=>$type, 'kampagneid'=>$kampagneid, 'dato'=>$dato, 'tid'=>$tid);
}

Hvis jeg fjerner $vis_data[] = array(); osv. så jeg kun har while($hent_data->fetch()) { } tilbage, så virker det stadigvæk, uden problemer. Hvordan kan det være? Så kan jeg vel undlade det? Eller har det en anden funktion?
Avatar billede olebole Juniormester
19. februar 2012 - 20:08 #56
Linjen lægger alle fundne rækker ind i array'et $vis_data. Det betyder, du efterfølgende kan hente forskellige rækker fra array'et - f.eks. kan du udskrive feltet kampagneid i den tredie række:

echo $vis_data[2]['kampagneid'];
Avatar billede BTEngineer Novice
19. februar 2012 - 20:23 #57
Okay :-)

Hvad hvis jeg eksempelvis har en række artikler der skal vises, dvs. alle 10 artikler på en gang.

Det plejer jeg jo at lave:

$show = mysql_fetch_array($query)) {

$show['artikelnavn'];
blabla...

}

Hvordan gør jeg det nu?
Det virker fint hvis jeg laver whilen gå ned over det jeg gerne vil have vist alle rækker af. Men lige så snart at jeg laver en ny forbindelse indeni den while med endnu en while, så dur det ikke.

Problemet er at jeg skal hente noget fra transaktioner og så vises alle transaktionerne, men der skal også navn på hvad det er for nogle transaktioner, og der skal kampagner-databasen så ind i billedet. Den vil ikke gå med til at jeg lave en while der også.. Den henter ingen data så.


<?php
if($hent = $mysqli->prepare("SELECT `pointprivat`, `type`,`kampagneid`, `dato`, `tid` FROM transaktioner WHERE bruger=? AND status=? ORDER BY id DESC")) {

$status_godkendt = "godkendt";

$hent->bind_param('ss', $bruger_id, $status_godkendt);

    $hent->execute();

$hent->bind_result($pointprivat, $type, $kampagneid, $dato, $tid);

$vis_data = array();

while($hent->fetch()) {
    $vis_data[] = array('pointprivat'=>$pointprivat, 'type'=>$type, 'kampagneid'=>$kampagneid, 'dato'=>$dato, 'tid'=>$tid);

//$hent = mysql_query("SELECT * FROM transaktioner WHERE bruger = '$id' AND status = 'godkendt' ORDER BY id DESC") or die(mysql_error());
//while($vis = mysql_fetch_array($hent)) {

if($hent_kampagner = $mysqli->prepare("SELECT `navn` FROM kampagner WHERE cpid=?")) {

$hent_kampagner->bind_param('s', $kampagneid);

$hent_kampagner->execute();

$hent_kampagner->bind_result($navn);

$vis_kampagner = array();

while($hent_kampagner->fetch()) {
    $vis_kampagner[] = array('navn'=>$navn);

//$loada = mysql_query("SELECT * FROM kampagner WHERE cpid = '$kampagneid'") or die(mysql_error());
//$showa = mysql_fetch_array($loada);

$optjent_k = number_format($pointprivat, 2, ',', '.');
?>
<div id="transaktioner">
<p class="dato"><?php if($type == "sw") {echo "<img src='/ikoner/plus.png' width='18px' height='18px' align='left' style='padding-right: 10px;'> ";} else {echo "<img src='/ikoner/minus.png' width='18px' height='18px' align='left' style='padding-right: 10px;'> ";} echo $dato; ?>, kl. <?php echo $tid; ?></p>

<p class="navn"><?php if($kampagneid == "u") { ?>..<? } else { echo $navn; } ?></p>

<p class="indtjening"><?php echo $optjent_k; ?> DKK</p>
</div>

<?php
}
}
}
}
?>
Avatar billede olebole Juniormester
19. februar 2012 - 20:33 #58
Sorry, men dette er indlæg #58 i denne tråd. Det må være nok nu  =)
Avatar billede BTEngineer Novice
19. februar 2012 - 21:29 #59
Det er rigtig, tak for hjælpen! :-)

Kan du ikke smide et svar, således at jeg kan få lukket den?
Avatar billede BTEngineer Novice
04. marts 2012 - 11:05 #60
Lukker..
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

Hiper A/S

IT-systemudvikler

Netcompany A/S

Test Specialist

Cognizant Technology Solutions Denmark ApS

Senior Test Manager

SEGES Innovation

DevOps med ambitioner

Politiets Efterretningstjeneste

Testere med flair for test management