Posts by FangorN

    Elke page access uitbreiden met 4+ queries lijkt mij minder efficiënt eerlijk gezegd.


    Aan de andere kant, als die dan van 1000 naar 1004 gaan maakt het ook niet zoveel uit eh :).

    Heb je geen 'dure' cronjob voor nodig!

    Nu ja, wat jij voorstelt is een "poor man's cron", oftewel een snippet die bij *elke* page-access wordt uitgevoerd. Behalve hoe zwaar een stuk code is zou je ook de frequentie waarmee deze wordt uitgevoerd in overweging moeten nemen. Daarnaast maak je het laden van een pagina weer wat zwaarder. En ben je eenzelfde soort bewerkingen (periodieke bijwerkingen) op verschillende plaatsen aan het regelen, wat ook niet fantastisch is.


    Je zult het ergens moeten regelen, ik zou dan nog steeds voor een cron opteren. Als het een uurlijke bijwerkactie is en je hebt een cron die elk uur wordt uitgevoerd dan lijkt mij dat meest logische plaats.


    heb zelf dit al geprobeerd en dat werkt niet :

    Wat heb je geprobeerd, wat is het gewenste resultaat en hoe wijkt het daadwerkelijke resultaat hier van af?


    En inderdaad, waar zijn je transacties en lockoperaties, holy sh*t son... Waarschijnlijk gebruikt dat spul enkel MyISAM tabellen? Veel succes om al je informatie kloppend (en onderling afgestemd) te houden dan.

    Een eerste (open) vraag zou zijn: wat verstaat men / de topicstarter onder een rankscript?


    Afhankelijk van die definitie zou je de (il)legaliteit eens verder onder de loep kunnen nemen.

    Het topic luidt "PHP PDO Class", dus ik neem aan dat je al een soort van wrapper hieromheen aan het schrijven bent?


    Het belangrijkste aan een wrapper class lijkt mij (o.a.) toegevoegde waarde. Als het enkel een soort van aliassen introduceert voor bepaalde methoden zonder dat het echt werk bespaart, dan heeft dat niet echt toegevoegde waarde.


    Het gebruik van wrapper classes in het algemeen is in zichzelf wel nuttig omdat dit hard coding vermindert - je zult geen PDO-specifieke functies meer in je code hebben, die zitten dan enkel in je PDO (MySQL?) wrapper.


    Maar tenzij je een volledige Database Abstraction Layer maakt, wat veel verder voert dan een wrapper (en waar er waarschijnlijk genoeg van te vinden zijn, je hoeft in dat opzicht niet opnieuw het wiel uit te vinden) blijf je hard coding houden. Immers, de SQL in jouw code is (redelijk) database-specifiek. Ook zou je kunnen kijken naar ORMs, Object Relational Mappers.


    Maar een (simpele) wrapper (die werk verzet) kan nog steeds van toegevoegde waarde zijn. Welke database-typen gebruik je trouwens? Als dit enkel MySQL is, waarom schrijf je dan geen wrapper voor MySQLi?


    Anyhowwwww... Als je met OOP bezig bent regel je het detecteren en afhandelen van fouten meestal / grotendeels via exceptions (en daarmee dus try-catch blokken). En exceptions zijn vooral bedoeld voor dingen die onverwacht fout gaan. Vanwege de aard van exceptions ("Er gaat iets fout en ik weet niet precies wat ik hiermee aan moet") is het ook niet aan de klasse zelf om te bepalen wat hiermee dient te gebeuren, dit doet een hogere laag. Een exception wordt zelden tot nooit afgehandeld op de plek waar deze werd gegenereerd. Je kunt wel classes extenden van elkaar, maar het lijkt mij niet dat je je database-exceptions als een soort van verlengstuk van je database-class moet zien. Dit zou wel een extension kunnen zijn van een eigen lijn van exception classes, maar hier moet je wat mij betreft ook waken voor wildgroei, het lijkt mij niet erg zinnig om voor elke class een exception class bij te schrijven, tenzij het lastig is om te identificeren waar fouten vandaan komen, maar daar heb je logging voor. Je zou een aparte exceptions-log kunnen maken waarin je je traces dumpt ofzo. Kortom, het is tevens zaak dat je dingen niet alleen op een manier oplost (en bij voorkeur dus de goede :p), maar ook op de juiste plaats.


    Wat ik denk dat vooral nu belangrijk is is dat je eerst duidelijk krijgt wat je precies wilt (kunnen) doen, en vervolgens hoe je dit op een juiste OOP-wijze vormgeeft want het klinkt nu een beetje alsof je een vaag idee hebt, maar nog niet precies hebt uitgewerkt hoe of wat. Het is ook belangrijk dat je vervolgens deze keuzes, die in wezen ontwerpbeslissingen zijn, kunt onderbouwen. Zoals bijvoorbeeld mijn eerdere vraag, indien je met PDO werkt, waarom PDO en niet iets anders?

    Niet opslaan wordt natuurlijk een beetje lastig. Immers, als je de foto kunt bekijken heb je hem in wezen al binnengehaald.


    Wat je wel zou kunnen doen is foto's beschermen tegen hotlinking. Daarmee wordt een rechtstreekse link aangemaakt naar de afbeelding vanaf een andere site waarmee die effectief jouw bandbreedte "steelt". Vroeger was dat natuurlijk wat meer een dingetje dan tegenwoordig omdat de prijzen voor data een stuk lager liggen of binnen bepaalde grenzen geen limiet hebben.


    Volgens mij was dit vrij eenvoudig realiseerbaar, Google simpelweg op (prevent) hotlinking + PHP + htaccess ofzo (als je Apache als webserver hebt of een compatibele die htaccess ondersteunt).


    Iets anders wat je ook zou kunnen doen is de site/foto's achter een login gooien en enkel mensen die je vertrouwt (of die willen betalen) toegang geven.

    Zodra er Europees Parlement en iets internet gerelateerds in één zin staat kun je er gif op innemen dat er een idioot besluit of idiote uitspraak volgt.


    Het dreigen met de stok (een boete, hoe origineel) is een zwaktebod waarmee min of meer wordt toegegeven dat men simpelweg geen controle heeft over een medium als het internet.


    Ook vraag ik mij af of er ooit bij zulk soort besluitvorming ooit nagedacht wordt over de uitvoerbaarheid van zo'n besluit.


    En wat als, om wat voor reden dan ook, buiten jouw schuld om jouw sites worden misbruikt voor de verspreiding van zulk materiaal? De meeste sites hebben gewoon disclaimers dat ze niet verantwoordelijk zijn voor de content die door anderen wordt aangeleverd. Zoiets zal YouTube ook zeker hebben.


    Dit is ongeveer het equivalent van een groentenwinkel die wordt beklad met hakenkruizen, en die dan zou moeten opdraaien voor "het verspreiden van propaganda".


    En nu kan het Parlement wel besluiten dat dit niet oirbaar is, maar wat volgt?


    Los daarvan, het verschilt per regime wat wordt bestempeld als "terroristische propaganda", dus dat is ook redelijk open voor interpretatie :p.


    Maar applaus, ik ben ervan overtuigd dat dit besluit de wereld een betere plek maakt...

    Zoals @Aaron hierboven aangeeft heeft hij geen enkele informatie, dus ook geen product id's ofzo.


    Neemt niet weg dat e.e.a. eenvoudiger kan. Je kunt alle velden die de productdata samenstellen batchgewijs toevoegen. Hierbij voorzie je alle velden van array-haken zonder een specifieke index. Je hebt dan geen JavaScript-constructies of wat dan ook nodig die tellers mee laten lopen. Je kunt simpelweg itereren over een van de productdata-velden en dat dan als index gebruiken om de andere bijbehorende velden aan te spreken. Dus wat @pottink, @D.Oomens en ik al min of meer voorstelden.


    Om toch ten overvloede maar een voorbeeld te geven:


    Je hebt dus behalve voor het interactief toevoegen van velden verder geen enkele JavaScript nodig.

    Ugh, arrays lijken mij een betere aanpak :p.


    En prijs is in principe informatie die je hebt, dus die hoef je niet te POSTen.


    Anders zou iemand zichzelf een korting kunnen geven :).


    En als je de prijs dan toch uit de database trekt voor een controle, waarom gebruik je die prijs dan niet direct? :)

    Zoals @D.Oomens al min of meer aangeeft: formulierelementen in HTML kennen ook array-structuren. Dit bereik je door een paar rechte haken achter de naam toe te voegen.


    Als elk item een id, hoeveelheid, prijs et cetera kent dan maak je voor elk van deze elementen een apart array:

    HTML
    <input type="text" name="item[]" value="<id hier>">
    <input type="text" name="quantity[]" value="">


    Prijs is afleidbaar, en weet je zelf al, die hoef je dus niet eerst in een formulier te stoppen, en er vervolgens weer uit te halen. Je zou wel een readonly prijs(tekst) op kunnen nemen in het formulier, zodat de invuller kan zien wat alles (totaal) kost.


    Bij de verwerking van het formulier (nadat je deze hebt gevalideerd uiteraard) itereer je over het item (sub)array, en gebruik je hierbij de index om de andere bijbehorende data te verzamelen, bijvoorbeeld zoiets:

    PHP
    // aanname: data is gevalideerd en is niet leeg
    foreach ($_POST['item'] as $index => $id) {
        $quantity = $_POST['quantity'][$index];
        // etc.
    }


    EDIT: je zou zelfs kunnen volstaan met het enkel doorgeven van een quantity, waarbij de key het item id is:

    HTML
    <input type="text" name="quantity[<item id hier>]" value="...">


    En dan wordt de loop:

    PHP
    // aanname: data is gevalideerd en is niet leeg
    foreach ($_POST['quantity'] as $productId => $quantity) {
        // etc.
    }

    Dit zou je kunnen doen met een variabele naam met behulp van een dubbele string ($$):


    PHP
    $i = 1;
    while (whatever) {
        $varName = 'string'.$i++; // post increment
        $$varName = 'something'; // let op de dubbele $
    }

    Maar hier kleven wel wat een aantal nadelen aan, zo "vervuil" je de huidige scope met een heleboel (soortgelijke) variabele( name)n. Daarbij programmeer je mogelijk informatie in de naam van de variabele (hard coding). Wat voor betekenis hebben deze 1, 2 et cetera?


    Zou het niet gewoon veel beter zijn om bijvoorbeeld één array te maken? Met dit volgnummer in de index ofzo? Wat voor bestaansrecht hebben al deze losse variabelen?


    Het kan dus wel, alleen zou ik deze aanpak niet aanraden. Je kunt beter investeren in een wat elegantere datastructuur. Hier zijn arrays bij uitstek voor geschikt.

    Het hoeft ook niet zo zwart wit (alles of niets) natuurlijk. En als er een module/lib ligt voor het communiceren met een API ga je die niet zelf schrijven. Uiteraard gebruik je dan dat soort componenten. Het maatwerk zou je ook nog steeds zo moeten schrijven dat dit potentieel herbruikbaar is. Ik stelde nergens voor dat je een baksteen zou moeten programmeren :).

    EDIT: stap 0 is natuurlijk het controleren van je errorlogs, kun je hier iets in vinden?
    Ben je ook nagegaan dat $errors leeg is?


    password is een gereserveerd woord, dus wellicht zou die kolom tussen `backticks` moeten staan?


    Voor debugging zou je tijdelijk de header() kunnen verwijderen en mysqli_error() kunnen inspecteren.


    Zou het ook niet beter zijn om enkel een user id op te slaan in de sessie, en elke page-refresh de gebruikersinfo op te halen aan de hand van een id en dan een user object te bakken ofzo? In plaats van dit in je sessie te zetten. Elke keer als je je profiel bijwerkt houdt dit in de huidige opzet ook een potentiële administratieve bijwerkactie van je sessie in. En al die extra administratie is niet nodig als je de informatie gewoon elke pagina ververst (middels een on-the-fly berekend User object).


    Je controleert ook nergens of de query slaagt maar je gooit de nieuwe username zo bam in je sessie :D.


    Ook zou ik registratie en het inloggen zelf splitsen, anders wordt dit een onoverzichtelijke brei. En meer in het algemeen zou je je logica meer in aparte acties kunnen compartimenteren. Elke actie is dan toegespitst op één specifieke handeling. Hoe je dit aan zou kunnen pakken heb ik een blogpost beschreven.


    Daarnaast zou ik geen dingen als $_SESSION['success'] gebruiken, tenzij dit bedoeld is als een soort van flash message, in welk geval ik het $_SESSION['messages'] zou noemen ofzo, om de (zeer) tijdelijke aard van dit soort sessie-inhoud te benadrukken. Dit hele subarray zou ook direct de eerstvolgende page-access geleegd moeten worden nadat deze berichten zijn weergegeven op je pagina.


    Enne, md5() voor password hashing? :/


    Enne, na header('Location: ...') hoort ALTIJD een exit; te staan. Headers zijn onderdeel van output, dus nadat ergens middenin je code header('Location: ...') staat word je niet direct naar de nieuwe locatie getransporteerd, dat gebeurt pas aan het einde van het script. Het aanwezig zijn of het ontbreken van een exit-statement kan het verschil betekenen tussen veilige en onveilige code.


    Je bent gewaarschuwd :evil: .


    Voorbeeld:

    PHP
    <?php
    if (isset($_SESSION['some_required_value']) === false) {
        header('Location: elsewhere.php');
    }
    // gevoelige code die gegevens kan manipuleren
    // ...
    ?>

    Dit is wat er dan achtereenvolgens gebeurt bij aanroep van dit script:
    1. de Location header wordt ingesteld op "elsewhere.php"
    2. de code in het onderdeel "// gevoelige code die gegevens kan manipuleren" >>>WORDT UITGEVOERD <<<
    3. na afloop van het script word je direct doorgestuurd naar "elsewhere.php"


    Daarom is het handig/verstandig om hiervoor een functie/methode te hebben zodat je dit nooit meer per ongeluk vergeet:

    PHP
    <?php
    function redirect($link) {
        header('HTTP/1.1 303 See Other');
        header('Location: '.$link);
        exit; // opdat we dit NOOIT meer vergeten
    }
    ?>

    Although is het wellicht toch handiger om het eigenlijk in een framework te gieten waar ik de laatste tijd toch meer voorstander van ben geworden als het gaat voor beginnende programmeurs om zaken te leren.

    Je bedoelt een bestaand framework zoals ZF, Laravel etc?


    Ja en nee. De bron moet ik je even schuldig blijven maar ik heb ergens een argument gelezen dat als je als bedrijf software ontwikkelt en daarbij inhouse bedrijfsspecifieke of -kritische applicaties of functionaliteit hebt, dat er best iets voor te zeggen is om dit gewoon zelf from scratch te ontwikkelen.


    Je moet daarbij wel beproefde principes en methoden gebruiken uiteraard gezien, ahem, het kleurrijke verleden van 'mafia games', maar je kunt deze best toepassen zonder de gebruikmaking van een framework. Je maakt dan in zekere zin een applicatiespecifiek framework. Dit komt de software ook ten goede omdat deze is afgestemd (tailored to fit) op het systeem, in plaats van een of ander prefab ding waar je misschien wat muren uit moet slopen.

    Een alternatief is bijvoorbeeld dat je een inleidende alinea in een apart veld opslaat, of deze paragraaf een speciale class meegeeft (zodat deze ook dikgedrukt wordt, als een soort samenvatting, dit zie je ook geregeld in kranten). Bij laatstgenoemde methode zou je alles in één veld kunnen opslaan, en die eerste paragraaf uit de tekst kunnen hengelen met een regexp.

    Meestal grijp je pas naar een regexp als alle eenvoudigere oplossingen zijn uitgeput. Vaak bestaan er goedkopere string-functies die precies/ongeveer doen waar je naar zoekt.


    Ik denk dat dit vraagstuk eenvoudig(er) opgelost kan worden door gewoon te kijken waar de laatste voorkomens van > en < zich bevinden met behulp van strrpos().


    Indien de laatste < na de laatste > valt (wellicht zul je nog andere randgevallen moeten controleren) wil dit zeggen dat je een niet-gesloten tag hebt. Je kunt dan de positie van de laatste < pakken.


    Let erop dat strlen() bytes telt, en geen karakters. Het is waarschijnlijk beter om string-bewerkingen met mb-functies te doen. In dat opzicht is het dus ook verstandiger om mb_strrpos() te gebruiken in plaats van strrpos().