Avatar billede riefart Seniormester
05. juni 2016 - 18:55 Der er 25 kommentarer og
1 løsning

Hvordan hentes cookie-værdier ind i søgesætning

Jeg har en side med køb og salg. På siden kan brugerne tilføje et emne til en huskeliste, hvorved der sættes cookies med navnet eks. koeb1012  eller salg3011 og opslagsnummeret som værdi, når der tilføjes til listen. Den første del af strengen refererer til den aktuelle tabel og den sidste til opslagsnumret.

Mit spørgsmål er : hvordan henter jeg cookie-værdierne og indlæser dem i et prepered statement, når brugeren klikker på sin huskeliste?
Avatar billede Slater Ekspert
05. juni 2016 - 19:00 #1
Som regel med $_COOKIE superglobal.

Hvis du skal vide mere præcist hvordan du hiver tingene ud, kan du så ikke lige lave en
var_dump($_COOKIE);
- og fortælle os hvad den spytter ud, så vi kan se præcis hvordan strukturen ser ud? Naturligvis efter der er tilføjet noget til cookies, så vi kan se det.
Avatar billede riefart Seniormester
05. juni 2016 - 19:06 #2
Den første var jeg godt klar over.
Jeg er rimelig nybegynder, så kan du sige hvordan jeg laver en var_dump($_COOKIE);
Avatar billede Slater Ekspert
05. juni 2016 - 19:33 #4
#2: Du skal faktisk bare skrive det i en .php-fil og vise den i en browser.

var_dump() udskriver hele indholdet af $_COOKIE, så vi kan se præcis hvad den indeholder, og dermed hvordan dataene skal trækkes ud af den.
Avatar billede riefart Seniormester
05. juni 2016 - 19:37 #5
Tøhø. Det havde jeg faktisk gjort men fik intet, indtil jeg så at fonten var sat til hvid på hvid baggrund....
Her  er hvad jeg får:
array(4) { ["PHPSESSID"]=> string(26) "9c8t3vt8nmldg0n83rbb9t43k2" ["salg1137"]=> string(4) "1137" ["salg1140"]=> string(4) "1140" ["salg1097"]=> string(4) "1097" }
Avatar billede riefart Seniormester
05. juni 2016 - 20:00 #6
Ronols. Disse links (#3) har jeg været omkring tidligere, men de bragte mig ikke tættere på en løsning.
Avatar billede Slater Ekspert
05. juni 2016 - 20:02 #7
Hah, den var ellers meget god.

Men her kan vi se, at dine opslagsnumre faktisk bliver gemt dobbelt. Hvis du har mulighed for det, er det lettere at hive ud (og giver mere mening) kun at gemme dit tabelnavn i indekset, og så bruge værdien til opslagsnummeret, så det bare bliver 'salg' => '1097' i stedet for 'salg1097' => '1097'

Hvis du kan det, kan du hive parrene ud med en simpel foreach, sådan:

foreach ($_COOKIE as $tabelnavn => $opslagsnummer)
{
    // Gør hvad du skal her med variablerne $tabelnavn og $opslagsnummer
}

Du får dog et lille problem her, da $_COOKIE også indeholder andre ting, så der skal nok tilføjes et lille filter til at fjerne de ting, der ikke er opslag. Det kan gøres på mange måder, men kræver at opslag har et unikt kendetegn, som andre ting ikke har. Har du f.eks. en liste over tabelnavne, så kan det gøres sådan:

$godkendte_tabelnavne = ['koeb', 'salg'];

foreach ($_COOKIE as $tabelnavn => $opslagsnummer)
{
    if ( in_array($tabelnavn, $godkendte_tabelnavne) )
    {
        // Gør hvad du skal her med variablerne $tabelnavn og $opslagsnummer
    }
}

- Men begge disse forudsætter, at du fjerner opslagsnummeret fra indekset, når cookies gemmes. Har du ikke den mulighed, skal de først splittes op. Lad mig lige vide.
Avatar billede riefart Seniormester
05. juni 2016 - 20:23 #8
Det ser meget forståeligt ud. Opslagsnummeret i cookiens navn var for at gøre hver cookie unik. Det er ikke noget problem at fjerne det men så overskrives cookien (eks "koeb) bare, når der vælges en ny til huskelisten.

Jeg bruger i øvrigt dette script til at sætte cookies:
<script type="text/javascript">
function setCookie(parm,value){
exp = new Date().getTime()+1000*60*60*24*365;
exp = new Date(exp).toGMTString();
document.cookie = parm+"="+value+";expires="+exp+";path=/"
}
</script>
Avatar billede Slater Ekspert
05. juni 2016 - 20:36 #9
Selvfølgelig. Jeg glemte naturligvis at nævne, at salgskoderne så skal tilføjes som et array.

Men det kan også sagtens bruges på din måde. Det er måske endda lettere, når det sættes fra Javascript. I så fald skal vi bare dele strengen op. Det er lettest hvis du tilføjer et separatortegn af en eller anden art. Eftersom det er et cookie-navn, må det ikke indeholde specielle tegn, men f.eks. bare en bindestreg "-" - så det hed "salg-1097". Så kan du sige

foreach ($_COOKIE as $tabelnavn => $opslagsnummer)
{
    $tabelnavn = current(explode('-', $tabelnavn));
    // osv...

Kan du ikke tilføje en separator, så skal vi lige vide hvordan formatet er. Er det altid bogstaver i første del og tal i anden? Kan der indgå danske bogstaver? Er tallet altid 4 cifre langt?
Avatar billede arne_v Ekspert
05. juni 2016 - 21:02 #10
Hvis data ikke er for store, saa var det en milighed kun at bruge en enkelt cookie med en vaerdi i JSON format.
Avatar billede riefart Seniormester
05. juni 2016 - 21:04 #11
Det ser ud som om, det er til at gå til.
Kan du sige mig, hvordan jeg tilføjer salgskoderne som et array i det script, jeg bruger?
Cookienavnet er enten ?koeb? eller ?salg?, værdien vil altid være et tal på 2-4 cifre.
Avatar billede Slater Ekspert
06. juni 2016 - 07:57 #12
#11: Jeg kan faktisk ikke huske, om du kan gemme som et direkte parsesable array-format fra Javascript, men du kan f.eks. bruge JSON som Arne nævner. Det kræver dog manuel parsing på begge sider, så umiddelbart er din egen løsning nemmere.

Hvis du ved at tabelnavnet altid er 'koeb' eller 'salg', så er det også meget let at dele det op, selv uden separator. F.eks. med
$tabelnavn = substr($tabelnavn, 0, 4);
- Det er ikke den bedste kodepraksis, fordi det hardcoder ind, at tabelnavnet skal være 4 tegn langt, men det virker. Mere modulært kunne du bruge et regex til at finde den del af strengen der ikke er tal. Det kunne gøres sådan:
preg_match('/^[^\d]*/', $tabelnavn, $matches);
$tabelnavn = $matches[0];

Hvis vi sætter det hele sammen, så bliver det sådan noget:

$godkendte_tabelnavne = ['koeb', 'salg'];

foreach ($_COOKIE as $tabelnavn => $opslagsnummer)
{
    $tabelnavn = substr($tabelnavn, 0, 4);

    if ( in_array($tabelnavn, $godkendte_tabelnavne) )
    {
        // Gør hvad du skal her med variablerne $tabelnavn og $opslagsnummer
    }
}
Avatar billede riefart Seniormester
06. juni 2016 - 18:28 #13
Jeg har lavet forskellige cookies af typen (salg1033, 1033) og (salg, 1033) for at prøve dine forslag.
Når jeg alene bruger:
foreach ($_COOKIE as $tabelnavn => $opslagsnummer)
{
        echo "$opslagsnummer<br />\n";
}
kommer alle værdier fint frem (både de ønskede og uønskede). Godt udgangspunkt!
Men når jeg bruger:
$godkendte_tabelnavne = ['koeb', 'salg'];

foreach ($_COOKIE as $tabelnavn => $opslagsnummer)
{
    if ( in_array($tabelnavn, $godkendte_tabelnavne) )
    {
        // Gør hvad du skal her med variablerne $tabelnavn og $opslagsnummer
    }
}
eller den "udvidede" i #12, kan siden ikke indlæses, og jeg får HTTP ERROR 500. Hvad gør jeg galt?
Avatar billede Slater Ekspert
06. juni 2016 - 19:22 #14
Det ved jeg ikke lige. Jeg har lige testet her, og det virker fint. Prøv at kopiere følgende kode ind i en fil, direkte, og kør den, uden noget andet i filen:
<?php

setcookie('salg1234', 1234);
setcookie('koeb6789', 6789);

$godkendte_tabelnavne = ['koeb', 'salg'];

foreach ($_COOKIE as $tabelnavn => $opslagsnummer)
{
    $tabelnavn = substr($tabelnavn, 0, 4);

    if ( in_array($tabelnavn, $godkendte_tabelnavne) )
    {
        echo $tabelnavn . ' => ' . $opslagsnummer . '<br>';
    }
}
Hvis det ikke virker, så må det næsten være en serverindstilling eller lignende.

Men det kunne jo også være rart, hvis du fik en fejlbesked, så man havde noget at gå efter. Hvis de er slået fra, kan du slå dem midlertidigt til for denne ene fil, ved at skrive følgende i toppen af filen (lige efter <?php):

error_reporting(E_ALL);
ini_set('display_errors', 1);
Avatar billede olsensweb.dk Ekspert
06. juni 2016 - 19:25 #15
vi er nok nød til at se hele test coden.

prøvede at omskrive coden lidt med inspiration fra #12


<script type="text/javascript">
    function setCookie(parm, value) {
        exp = new Date().getTime() + 1000 * 60 * 60 * 24 * 365;
        exp = new Date(exp).toGMTString();
        document.cookie = parm + "=" + value + ";expires=" + exp + ";path=/"
    }
    setCookie("salg", Array("1234", "987", 35987));
    setCookie("kob", Array("753", 618));
    setCookie("test", Array(666, 112, 911));
</script>
<?php
$cookie = $_COOKIE;
// var_dump($cookie);

$godkendte_tabelnavne = ['kob', 'salg'];
foreach ($cookie as $tabelnavn => $opslagsnummer) {

    echo $tabelnavn . " ". $opslagsnummer. "<br>";
    if (in_array($tabelnavn, $godkendte_tabelnavne)) {
        echo $tabelnavn . " indeholder : ";

        $ar = explode(",", $opslagsnummer);
        for ($i = 0, $lng = count($ar); $i < $lng; $i++) {                   
            echo $ar[$i] . " ";
        }
        echo "<br>";   
        // Gør hvad du skal her med variablerne $tabelnavn og $opslagsnummer
    }
}
?>


output

salg 1234,987,35987
salg indeholder : 1234 987 35987
kob 753,618
kob indeholder : 753 618
test 666,112,911


da php coden ligger på sammen side ser man først cookien slå igennem næste gang siden læses, men det kan klares med noget post og isset
Avatar billede olsensweb.dk Ekspert
06. juni 2016 - 19:33 #16
#14

Men det kunne jo også være rart, hvis du fik en fejlbesked, så man havde noget at gå efter. Hvis de er slået fra, kan du slå dem midlertidigt til for denne ene fil, ved at skrive følgende i toppen af filen (lige efter <?php):

man har da altid slået error_reporting og display error til under udvikling ikk ??.
fejl beskeder er en stor del af udvikling, uden disse udvikles der i blinde. fejl og advarsler skal rettes, (advarsler skal man være opmærksomme på, og rette, hvis det er relevant)
Avatar billede Slater Ekspert
06. juni 2016 - 19:42 #17
#16: Hvis man har et udviklingsmiljø, klart. Det er kropumuligt at udvikle noget bare lidt kompliceret, hvis man ikke kan se fejlbeskeder. Men der er tilsyneladende mange der udvikler direkte på deres produktionsserver, og i de tilfælde er det et temmelig dårligt råd, at bede dem slå fejlmeddelelser til globalt.

Det lå uden for scope af denne tråd at snakke meget mere om det, så jeg valgte bare at nævne den simple, sikre løsning. Du er for min skyld meget velkommen til at sige mere om det.
Avatar billede olsensweb.dk Ekspert
06. juni 2016 - 20:15 #18
>Men der er tilsyneladende mange der udvikler direkte på deres produktionsserver, og i de tilfælde er det et temmelig dårligt råd, at bede dem slå fejlmeddelelser til globalt.

ja derfor laver man en extern fil og ligger ind i toppen af sin php fil, at rode med php.ini eller php.so som den vist hedder på linux skal man være varsom med

jeg har denne externe fil liggende

<?php
define('IN_DEBUG_MODE', true); // Sæt til false i production mode
if (IN_DEBUG_MODE) {
    ini_set("display_startup_errors", "on");
    ini_set("display_errors", "on");
    ini_set("html_errors", "false");
    error_reporting(-1); // -1 viser alle slags fejl beskeder
    ini_set("ignore_repeated_errors", 0);
} else {
// Turn off all error reporting
    error_reporting(0);
}
?>

som jeg laver en include_once på alle mine sider.

og så bruger jeg browseren (F12).
chrome udvidet med Web Developer
eller
firefox udvidet med firebug
Avatar billede riefart Seniormester
06. juni 2016 - 21:00 #19
Jeg forstår det ikke. Har prøvet både #14 og #15 med fejlbeskeder slået til. Og jeg får bare samme fejl hver gang (HTTP ERROR 500). Ingen resultat ejheller i udviklerværktøjer.
Avatar billede olsensweb.dk Ekspert
06. juni 2016 - 21:21 #20
500 Internal Server Error
http://pcsupport.about.com/od/findbyerrormessage/a/500servererror.htm
https://mediatemple.net/community/products/dv/204644990/why-am-i-getting-a-500-internal-server-error-message
https://www.w3.org/Protocols/HTTP/HTRESP.html

står der et nummer efter 500 ?? feks 500.19
anvender du .htaccess
prøv at lave en ren html side, det lyder som din code er meget defekt
Avatar billede riefart Seniormester
06. juni 2016 - 22:34 #21
Men det er det, der er så mærkeligt: for det eneste der er i php-dokumentet er #7...og det virker. Når jeg erstatter det med #12 eller dit forslag, får jeg bare serverfejlen og intet andet. Ikke andet end 500.
Jeg har en .htaccess-fil (til subdomains)).
Avatar billede riefart Seniormester
06. juni 2016 - 22:44 #22
Min server kører i øvrigt php 5.3.29.
Avatar billede riefart Seniormester
06. juni 2016 - 22:59 #23
Så kom jeg lidt nærmere:
Når jeg fra #14 fjerner disse to linier:
$godkendte_tabelnavne = ['koeb', 'salg'];
if ( in_array($tabelnavn, $godkendte_tabelnavne) )
får jeg output!
salg => 1137
salg => 1140
salg => 1097
salg => 1166
Det er pudsigt. Men det løser jo problemet.
Avatar billede arne_v Ekspert
07. juni 2016 - 02:03 #24
$godkendte_tabelnavne = array('koeb', 'salg');
if ( in_array($tabelnavn, $godkendte_tabelnavne) )

[] for arrays kom foerst i PHP 5.4!
Avatar billede arne_v Ekspert
07. juni 2016 - 02:43 #25
Og jeg menr stadig at JSON ideen er god.

Demo:


<?php
define('LISTS_COOKIE', '__LISTS');
define('LIST_NAME', 'NAM');
define('LIST_VALUES', 'VAL');

function get_cookie() {
    return isset($_COOKIE[LISTS_COOKIE]) ? json_decode($_COOKIE[LISTS_COOKIE], true) : array();
}

function display_lists($lists) {
    foreach($lists as $list) {
        $name = $list[LIST_NAME];
        $vals = implode(' ', $list[LIST_VALUES]);
        echo "$name : $vals<br>";
    }
}

function set_cookie($lists) {
    setcookie(LISTS_COOKIE, json_encode($lists));
}

// demo
$lists = get_cookie();
display_lists($lists);
foreach($lists as &$list) {
    $list[LIST_VALUES][] = '*';
}
$lists[] = array(LIST_NAME => 'L' . (count($lists) + 1), LIST_VALUES => array('*'));
set_cookie($lists);
?>
Avatar billede riefart Seniormester
07. juni 2016 - 07:01 #26
Se, forklarere det jo alt.
Jeg har lettere ved at forstå syntaksen i #14, og den passer godt med, det jeg videre skal foretage mig.
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