Posts by FangorN

    @MiCa-


    Wat pointers:
    class DBConfig
    - er zit geen charset in je DSN :( (vanaf PHP 5.3.6, anders moet je dit via PDO::MYSQL_ATTR_INIT_COMMAND regelen)
    - gebruik een IP in plaats van localhost, dat scheelt je weer een lookup
    - het lijkt mij niet nodig om de DSN, dbUser of dbPassword te onthouden?
    - het attribute wat je waarschijnlijk probeert in te stellen is PDO::ATTR_ERRMODE, niet PDO::ERRMODE_EXCEPTION, mogelijk hebben deze dezelfde numerieke waarde, maar ik zou daar dan toch de goede constante voor gebruiken :)



    class UserDAO
    - wat je eigenlijk wilt controleren met de checkUsernameExsists methode (let op spelling :)) is of het precies één resultaat oplevert, dit kun je misschien beter doen met COUNT(id) en dan kijken of fetchColumn de waarde '1' oplevert (vergelijk met mysql_num_rows()); NB: als je dit als precheck wilt gebruiken voor het toevoegen van een gebruiker zal dit trouwens ook in een transactie i.c.m. FOR UPDATE gebruikt moeten worden
    - kun je niet beter een database-object meegeven bij creatie of uit een registry halen of (mogelijk omstreden) van je db class een static ding maken (factory)? je maakt nu wel elke keer een nieuw database object aan als er al eerder ergens een database object was; dit lijkt mij een verspilling van resources? dit zal overigens niet resulteren in een tweede connectie naar je database omdat je DSN waarschijnlijk onveranderd is, als deze hetzelfde is als die van een eerdere connectie, dan wordt deze hergebruikt; dit kan wel mogelijk weer voor problemen zorgen bij het definitief afsluiten van een connectie, waarschijnlijk blijft deze bestaan zolang er nog één connectie "open staat", waarschijnlijk is het verstandiger om een database-object (de connectie naar een specifieke database) maar 1x te maken ten einde verwarring te voorkomen (oftewel, maak zo'n object eenmalig aan en geef deze op enigerlei wijze door bij de creatie van andere objecten die een db-connectie nodig hebben)

    Fair enough.


    Als vervanging voor de oorspronkeljike MySQL API (alle functies die beginnen met mysql_) zijn er twee andere smaken beschikbaar: MySQLi en PDO.


    Als je een snelle omzetting wilt doen in een (of) enkel(e) script(s) dan lijkt mij MySQLi (MySQL improved) het meest geschikt, omdat dit het dichtst bij de oorspronkelijke MySQL API staat.


    MySQLi heeft een procedurele en een object georienteerde variant. Beide hebben voor- en nadelen. Het voordeel van de procedurele variant is bijvoorbeeld dat je (theoretisch) alle voorkomens van mysql_... haast kunt zoeken-en-vervangen door een mysqli_... variant.


    Als het slechts een handjevol scripts betreft zou ik (in eerste instantie) geen gebruik maken van PDO (PHP Data Objects). Dit is namelijk een data abstractie laag, en deze is niet geschreven voor een specifieke database, maar hierbij moet je gebruik maken van een specifieke driver (PDO_MYSQL) om met je MySQL-database te communiceren.


    Omdat PDO an sich niet is geschreven voor enige database, is deze op voorhand dus ook niet optimaal ingesteld voor gebruik van een specifieke database zoals MySQL. Er zit dus nog wel een zekere leercurve ten aanzien van de gebruikmaking van PDO zelf en driver-specifieke instellingen. Met name dat laatste willen mensen nogal eens vergeten, en roemen PDO vooral omdat "deze ondersteuning biedt voor een heleboel databases". Daarbij vergeten ze voor het gemak ook even dat PDO van zichzelf geen Data Access Abstraction Layer heeft, oftewel, de syntax (vorm) van je SQL-code is nog steeds database-specifiek en databases zijn daarom niet vrij inwisselbaar, in ieder geval niet zonder aanpassing van de SQL code.


    Enfin, MySQLi dus, als je het in eerste instantie simpel wilt houden. Je tegelijkertijd verdiepen in PDO kan trouwens ook geen kwaad.


    Punten uit de vorige post zijn nog steeds van toepassing: let op character encoderingen en security in het algemeen (filter input, escape output).

    @Starohosting heb je de afgelopen 10 jaar het nieuws niet gevolgd? Zo lang is de mysql-extensie al ongeveer verouderd.


    En waarschuwt je host niet wanneer er wordt geupgra... oh, dit was jij zelf? En nu, kun je niet meer terug? Heb je dit niet eerst in een testomgeving getest want dit komt toch min of meer neer op een migratie? Jeweetwel, kijken of dingen nog werken in een nieuwe opstelling.


    Anyhoo, misschien loont het inderdaad de moeite om eens een (grondige) schoonmaak te doen in je code of dingen gewoon opnieuw te schrijven. Zoals @Opium terecht aangeeft, dit zal van invloed zijn op je gehele website.


    Het is tegenwoordig ook hip om te zorgen dat je chararacter encoderingen overal in de pas lopen. Dit is in ieder geval iets wat mist bij het maken van je connectie, en ook in de (door zichzelf gelikete? wtf lol) "verbetering" van @Puurhost - het (expliciet) selecteren van een character encoding via een set_charset() functie of methode.


    Ook is security tegenwoordig een hot topic. Als je je bedient van het credo "filter input, escape output", je ook daadwerkelijk snapt wat dit betekent en hier naar handelt kom je al een heel eind.


    Het zou niet misstaan om eens aandachtig (wellicht in versneld tempo) kennis te maken met (onder andere, maar niet uitsluitend) deze twee onderwerpen. Hiermee kun je jezelf een hele hoop ellende besparen.


    Trouwens, als je alle query aanroepen niet hard gehardcode (mysql_connect, mysql_query etc.) maar via een wrapper had laten verlopen, was het aanpassen van deze functionaliteit mogelijk beperkt geweest tot het aanpassen van de implementatie van deze wrapper. Nu zul je heel je website door moeten.

    Ik zou het zo doen, het is (iets) korter, meer to-the-point en meer in lijn met een whitelist:


    Al doet het syntactisch waarschijnlijk hetzelfde als jouw codefragment vind ik deze toch wat prettiger lezen. Het doet ook precies wat het moet doen, niet meer, niet minder.

    @ruttydm dat werkt niet zoals je wellicht zou denken.


    Als je voor $sorton bijvoorbeeld "reward_hour" invult (wat een toegestane waarde is) dan wordt sorton toch gelijk aan "average_reward".


    Je if-statement klopt niet. Je hebt daar namelijk staan ... or "<niet lege string>" or ... . Dat is altijd waar, waardoor het if-statement in zijn geheel ook altijd waar is. Een controle met in_array lijkt mij beter dan deze (niet-kloppende) constructie.

    Het is zeker niet verkeerd om ALTIJD je query input te gaan binden, maar het is ook gewoon niet altijd nodig, gebruikers input zonder enige validatie moet gewoon altijd gebind worden om inderdaad injectie tegen te gaan.

    Sterker nog, het *kan* niet altijd, en dat is hier juist het probleem. Zoveel stond al in mijn eerste reactie.


    Vervolgens begint de discussie een beetje te vervagen met wat de rol van een programmeur en een gebruiker zou zijn. Ik heb sinds mijn eerste reactie eigenlijk geen nieuwe relevante informatie ten aanzien van dit topic de revue zien passeren.


    De topicstarter moet gewoon alle input die niet via prepared statements verloopt filteren, te meer omdat deze rechtstreeks uit $_GET lijkt te komen.


    Hoe je vervolgens fouten afvangt (of je nu een foutmelding produceert -wat niet erg gebruiksvriendelijk is- of terugvalt op een default waarde) is uitwerking / zijn details, en heeft ook weinig van doen met het oorspronkelijke probleem. Het oorspronkelijke probleem was dat de topicstarter iets probeerde te binden wat niet gebind kon worden. Vervolgens geef ik aan:


    - dat / waarom dit niet altijd kan
    - hoe je dit dan wel doet
    - en waar je daarbij op moet letten


    Volgens mij kun je geen vollediger antwoord dan dat geven, behalve misschien dat je ook de complete oplossing uitschrijft. Maar als je dat (in dit eenvoudige geval) niet zelf kunt, dan zou je deze tak van sport niet moeten bedrijven.


    @ruttydm uit jouw code kan niet opgemaakt worden hoe $sorton en $order "veilig gemaakt" zijn.

    Toevoeging op code van @MiCa-

    PHP
    $result = $db->prepare("SELECT * FROM faucets ORDER BY `$sorton` $order");
    $result->execute();

    Hiermee doe je het idee van prepared statement min of meer teniet (door rechtstreeks waarden in je querystring te plakken in plaats van te binden via parameters of values).


    Helaas is het niet mogelijk om dit op een andere manier te doen omdat het simpelweg niet mogelijk is om tabelnamen en -kolommen te binden op deze manier (of extra SQL te schrijven, for that matter). Daarvoor zijn prepared statements niet bedoeld, het is enkel de bedoeling dat je DATA bind, en niets anders.


    Met het bovenstaande introduceer je wel weer de mogelijkheid voor SQL injectie. Omdat je de spelregels van prepared statements met bovenstaande constructie omzeilt is je query hier weer vatbaar voor. Zorg dus dat je met whitelists werkt, oftewel definieer wat toegestane waarden zijn voor $sorton en $order en zorg ervoor dat ze terug kunnen vallen op een geldige (en zinnige) default waarde.


    (Hetgeen in de vorige alinea wordt beschreven komt in wezen neer op input filtering)


    Er zit niets in, het is een lege output. De notice is een melding dat het leeg is. Die error kan/mag je gerust uitschakelen.

    Dit soort foutmeldingen (undefined index i) mag je niet op voorhand onder het tapijt schuiven omdat dit mogelijk een indicatie is van een (of meer) bug(s).


    Ik vind het dan ook vreemd dat je aanraadt dit soort indicaties te negeren :/.


    Kijk waar dit vandaan komt: als je gebruik maakt van een API: roep je deze misschien op de verkeerde manier aan, als dit je eigen code betreft: tijd voor een debug-sessie.


    Als er dingen misgaan en je kent nog geen oorzaak mag je niet op voorhand dingen uitsluiten omdat die mogelijk (mede-)veroorzaker zijn van het probleem.

    De hoogte van de boetes zijn soms te idioot voor woorden, maar.


    Je bent illegaal content aan het streamen / delen en deze gang van zaken gebeurt via een populair (?) programma dus waarschijnlijk gebeurt dit veelvuldig en in grote getale. In zodanige mate dat je zou kunnen stellen dat de distributeurs van het bronmateriaal potentieel (enorm) veel inkomsten mislopen op deze manier.


    Serieus, wat verwacht je wat er vervolgens gebeurt.


    Heeft niemand een Napster-erlebnis, of is dat van voor jullie tijd :). PCT heeft door zijn populariteit zijn kop gewoon te ver boven het maaiveld uitgestoken.


    EDIT: @Opium bittorrent als medium is niet verboden. De content die je daarmee verspreid waar je normaal voor zou moeten betalen... nuff said.

    Waarom lees je niet gewoon de file regel per regel uit en skip je hierbij lege regels?


    Als je invoer niet consistent is (waarbij elke "resultaatregel" uit precies niet-lege 5 items bestaat, die tevens in de goede volgorde staan) dan kun je het automatisch genereren wel vergeten, omdat het dan geen patroon volgt.


    Indien je invoer wel consistent is, zou je bijvoorbeeld data van 5 niet-lege regels kunnen verzamelen, en deze als "resultaatregel" kunnen wegschrijven. Daarna begint het spel weer opnieuw net zolang totdat je het hele bestand hebt uitgelezen.


    Het bovenstaande lijkt mij een zeer simpel algoritme wat zou moeten werken als je invoer klopt.


    code:

    Als iets te mooi klinkt om waar te zijn, is dit ook meestal het geval :).


    Hosters zullen nog steeds geld vragen voor dit soort diensten, ook al zijn er aan de gebruikmaking van deze variant (vooralsnog) geen kosten verbonden. Ik denk dat zij hier blij mee zullen zijn, maar "eindgebruikers" die ergens bij een internetboer een website hebben draaien hoeven hier (financieel) niet veel van te merken.


    Dan is de vraag, moét alles ge-encrypt worden? Volgens mij niet, en soms lijkt mij dit zelfs onwenselijk.


    Desalniettemin maakt dit het gebruik (de toepassing) van HTTPS wel een stukje laagdrempeliger, wat natuurlijk toegejuicht mag worden.


    Ik ben trouwens ook benieuwd hoe de CA-wereld deze nieuwe partij ontvangen heeft. Ik denk dat zij op zijn zachtst gezegd "not amused" zijn. Het is goed om te zien dat die rebellen van EFF hier weer bij betrokken zijn :).


    Had hier nog niet van gehoord - thx.

    - werk met één tijdslijn, je gebruikt nu twee "klokken": time() (PHP) en NOW() (MySQL); mogelijk staan beide klokken niet gelijk, kies een van de twee (PHP of MySQL) die bepaalt hoe laat het is


    - werk ook met één (eenduidige) tijdszone, mogelijk wordt in PHP een hele andere tijdszone gebruikt dan in MySQL, dus zelfs als je één klok gebruikt kan dit toch verschillende betekenissen hebben (een tijd kan op verschillende manieren geinterpreteerd worden) afhankelijk van hoe/waar je hier naar kijkt


    Verder staat er geen enkele regel commentaar in bovenstaande code die aangeeft hoe deze zou moeten werken en maakt deze -zoals eerder aangegeven- gebruik van verouderde functies en onveilige constructies. Ik denk daarom dat het niet echt de moeite loont om hier "quick fixes" in uit te voeren, te meer omdat op andere plaatsen waarschijnlijk soortgelijke problemen spelen - de oplossingen die je toepast in deze code zou je dan ook op andere plaatsen moeten toepassen om er verzekerd van te zijn dat alles in de pas loopt.

    (Heel) strict genomen moet na Location een volledige URL volgen, probeer het daar eens mee.


    Daarnaast maakt een header() aanroep deel uit van HTTP headers. Deze moeten voor wat voor output dan ook verstuurd worden of je moet alle output (van in ieder geval voor dat moment) bufferen.


    Beginnen met het bufferen van output net voor het moment dat je een header verstuurt is mogelijk (en in dit geval, waarschijnlijk) niet genoeg... Dit moet echt vanaf het begin, of je zorgt voor een duidelijke scheiding tussen de uitvoer van PHP acties en het afdrukken van een pagina.


    De eerste methode is makkelijker, maar er is dan een groter gevaar voor "spaghetti code" omdat je minder gedwongen wordt een en ander gestructureerd aan te pakken :).


    Heb je het melden en weergeven van fouten al aangezet? Grote kans dat hierna de aloude / welbekende foutmelding "headers already sent" voorbij komt.

    Het klinkt niet alsof je (al) werkt met een version control systeem (VCS)? Wellicht is dat wat je zoekt? Het lijkt mij een beetje overkill om alles te synchroniseren, het gaat waarschijnlijk om specifieke collecties bestanden (bijvoorbeeld code verdeeld over verschillende projecten)?


    Andere bestanden zou je weer centraal kunnen organiseren met webapplicaties zoals Dropbox.


    Als je allerlei dingen online wilt opslaan ben je natuurlijk wel een beetje beperkt in je handelen als je een brakke internetconnectie hebt...

    Heb je een firewall nodig om lokaal een verbinding te maken? :/


    Het klinkt (mede) alsof je mysql proces gewoon niet actief was.


    Dat, of de vertaling localhost --> 127.0.0.1 gaat niet goed terwijl je grants aan 127.0.0.1 gekoppeld zijn terwijl je connect met localhost.


    Het is trouwens altijd beter om op IP-basis te werken, dat scheelt je weer een lookup.


    Overigens zou 3306 de standaard poort voor MySQL moeten zijn (ook bij gebruikmaking van MySQLi), dus die zou je nooit expliciet in hoeven te stellen, tenzij je PHP-configuratie al om een of andere reden afwijkt van deze standaard, wat op zich wel vreemd is.

    Dat zou een makkelijkere oplossing zijn geweest, ware het niet dat de gewenste informatie (onder andere) de laatste message van een conversation is (en niet enkel simpelweg de datum), volgens mij kun je niet garanderen dat je op die manier de laatstgeplaatste message terugkrijgt als je groepeert op datum...


    But feel free to try :).