[PHP] Dit kan efficiënter

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb nu dit lapje code:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function valideer_nieuw_in_database_2($gegevensbank, $tabel, $reeks_waarde){
    mysql_select_db($gegevensbank);
    $lijn = "SELECT * FROM " . $tabel . " WHERE ";
    foreach($reeks_waarde as $kolom => $waarde){
        $lijn .= $kolom . " = " . $waarde;
        if(next($reeks_waarde)){
            $lijn .= " AND ";
        }
    }
    $lijn .= ";";
    $resultaat_nieuw_in_database = vqu($lijn);
    if(mysql_num_rows($resultaat_nieuw_in_database) > 0){
        $valideer_nieuw_in_database['foutboodschap'] = "Dit zit reeds in de database.";
        return toon_foutboodschap($valideer_nieuw_in_database['foutboodschap']);
    }
}


Die functie roep ik bijvoorbeeld zo aan:

PHP:
1
2
3
4
5
6
<?php
    $reeks = array();
    $reeks['project_id'] = 1;
    $reeks['dimensie_id'] = 1;
    echo(valideer_nieuw_in_database_2("eportfoliotest", "aandeel", $reeks));
?>


Dat werkt dus goed, en het lijkt me ook een multi-inzetbare functie. Maar er wringt toch iets met de manier waarop ik zo'n dynamische query opbouw. Zijn hier geen mooiere manieren voor?

Acties:
  • 0 Henk 'm!

  • orf
  • Registratie: Augustus 2005
  • Nu online

orf

Met dynamisch een query opbouwen is niets mis, maar waarom doe je een een SELECT * als je alleen maar het aantal rijen wilt weten?

SELECT COUNT(1) is nogal wat efficienter.

waarom gebruik je een array met één value als return waarde?

Acties:
  • 0 Henk 'm!

  • Skinkie
  • Registratie: Juni 2001
  • Laatst online: 09-06-2020

Skinkie

Op naar de 500

" " -> ' '

Steun Elkaar, Kopieer Nederlands Waar!


Acties:
  • 0 Henk 'm!

  • GF
  • Registratie: April 2002
  • Laatst online: 14-09 16:23

GF

Paar aandachtspunten

- Naamgeving methoden
- COUNT in je select gebruiken ipv aantal gevonden records tellen
- SQL injection (?)
- Geen return wanneer if statement niet voldoet
- Gebruik van arrays waar een normale variable voldoende is
- Gebruik sprintf ipv concats in '$kolom . " = " . $waarde;'. Maakt het leesbaarder

Acties:
  • 0 Henk 'm!

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

wtf is valideer_nieuw_in_database_2? Verzin 'n naam die een sterveling ook kan begrijpen :)

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

(jarig!)
Dat heeft een dusdanig kleine invloed op de executietijd dat ie zeker met moderne php's (>4.1 ofzo) eigenlijk niet meer meetbaar is. Dus die tip is tamelijk loos.

Kwa code-duidelijkheid zou ik overigens niet een "toonbare" foutmelding uit de 'valideer-functie' laten rollen, maar eerder een boolean waarde oid.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
orf schreef op vrijdag 20 april 2007 @ 22:29:
Met dynamisch een query opbouwen is niets mis, maar waarom doe je een een SELECT * als je alleen maar het aantal rijen wilt weten?

SELECT COUNT(1) is nogal wat efficienter.

waarom gebruik je een array met één value als return waarde?
Goede tip! En ik heb even de code opnieuw bekeken - vroeger deed ik wel wat specifieks met die arrays, maar dat is nu inderdaad niet meer nodig.
GF schreef op vrijdag 20 april 2007 @ 22:44:
Paar aandachtspunten

- Naamgeving methoden
- COUNT in je select gebruiken ipv aantal gevonden records tellen
- SQL injection (?)
- Geen return wanneer if statement niet voldoet
- Gebruik van arrays waar een normale variable voldoende is
- Gebruik sprintf ipv concats in '$kolom . " = " . $waarde;'. Maakt het leesbaarder
- Die naamgeving vind ik nogal subjectief.
- Ik heb nog een boel andere valideer_xxx-functies - de gehele code blijft voor mij wel leesbaar.
- Voor SQL-injectie doe ik op een hoger niveau een aantal controles; dit is een functie die ik intern aanroep. Ik zou inderdaad een false kunnen returnen - bekijk ik dan ook.
- Goede tip, die sprintf - nieuw voor me.
ACM schreef op vrijdag 20 april 2007 @ 23:29:
[...]

Kwa code-duidelijkheid zou ik overigens niet een "toonbare" foutmelding uit de 'valideer-functie' laten rollen, maar eerder een boolean waarde oid.
Heb ook met die gedachte gespeeld. Het gaat hier om een formuliervalidatie, en dan zou ik voor elk formulier per veld moeten instellen wat de fout precies is. Ik koos ervoor om de functie een algemene, doch heldere melding terug te laten geven.

Bouwen jullie verder ook op die manier dynamische queries op? Het ziet er zo vies uit met die idiote if-controle in die foreachlus.

Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Regel nummer 1: SCHRIJF JE CODE IN HET ENGELS!!!
(sorry maar ik heb echt een absolute grafhekel in taal afhankelijk geprogrammeerde code. Wel eens php gezien in het duits of frans ofzo? Verschrikkelijk irritant. Elke programmeertaal is al een taal op zich, met keywords en functie namen in het engels, schrijf dan alsjeblieft gewoon je variabele namen in het engels :'(
Regel nummer 2: Functies met een cijfer er (do_something_2) vertellen je überhaupt dat je iets fout doet. Als een functie zo veel op de vorige lijkt dat je er een 1 of een 2 achter zet dan kan je het waarschijnlijk efficient zo coden dat het in 1 functie werkt.
Regel nummer 3: Zorg er voor je code zo schrijft dat een andere programmeur zonder handleiding met jouw code aan de slag kan en niet een aantal wtf momenten heeft (zie regel 1)

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
function row_exists($db, $table, $values)
{
     mysql_select_db($db);
     $where = array();
     foreach($values as $key => $value)
     {
        $where[] = $key.' = "'.addslashes($value).'"';
     }
     // wtf is vqu  :? (wtf moment dus)
     $queryresult = mysql_query("SELECT * FROM {$table} WHERE ".implode(' AND ', $where));
     return mysql_num_rows($queryresult) > 0;    
}

Zoiets is dan een betere optie denkik. Je bent nog niet helemaal klaar want je mist hier nog je mysql connection link, maar ik gebruik dan ook niet elke dag de mysql* functies.
Kijk voor de gein eens naar al gestandaardiseerde database classes en ga alsjeblieft niet opnieuw het wiel uitvinden op gebieden waarvoor anderen dat al voor je gedaan hebben.

[ Voor 15% gewijzigd door SchizoDuckie op 20-04-2007 23:59 ]

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • GF
  • Registratie: April 2002
  • Laatst online: 14-09 16:23

GF

Verwijderd schreef op vrijdag 20 april 2007 @ 23:43:
- Die naamgeving vind ik nogal subjectief.
Toch is het meerendeel het er hier over eens dat hier nog wel wat aandacht aan geschonken mag worden. Ik vindt dit soort namen niets zeggend. Tevens nummers in namen is ook geen goed teken imo.

Wat betreft de taal die je gebruikt voor commentaar/vars etc: dit is persoonlijk. Zelf negeer ik alle niet in engels geschreven code puur omdat het er niet uitziet en de meeste vertalingen gewoon ruk zijn (vb: foutboodschap?? -> foutmelding lijkt me beter). Daarnaast kan een buitenlander het dus al niet lezen en dus ga je je uiteindelijk in de vingers snijden als je iets moet overdragen (of iemand anders moet er ook mee werken)

[ Voor 4% gewijzigd door GF op 20-04-2007 23:59 ]


Acties:
  • 0 Henk 'm!

  • Peter
  • Registratie: Januari 2005
  • Laatst online: 13-09 17:10
Je kan je strings het beste tussen enkele quotes ( ' ) zetten ipv. tussen dubbele quotes ( " ), en hierbij meteen variables buiten quotes halen. Dubbele quotes worden geparsed voor variablen die erin zitten (zoals jij bijvoorbeeld de {$table} in $queryresult hebt), enkele quotes niet. Ze forceren je dus om variablen buiten quotes te houden (wat goed is!), en versnellen de boel ook nog eens redelijk, zeker als je veel strings gebruikt.
.
PHP:
1
$queryresult = mysql_query( 'SELECT * FROM ' . $table . ' WHERE ' . implode( ' AND ', $where ) );

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

(jarig!)
Verwijderd schreef op vrijdag 20 april 2007 @ 23:43:
Heb ook met die gedachte gespeeld. Het gaat hier om een formuliervalidatie, en dan zou ik voor elk formulier per veld moeten instellen wat de fout precies is. Ik koos ervoor om de functie een algemene, doch heldere melding terug te laten geven.
Het voordeel van dat niet doen is dat je de functie ook later op andere plekken kan gebruiken, nu is ie alleen maar bruikbaar als form-met-foutmelding-validatie. Terwijl je ook heel goed de echo op regel 5 aan kan passen.
Bouwen jullie verder ook op die manier dynamische queries op? Het ziet er zo vies uit met die idiote if-controle in die foreachlus.
Ik vind het zelf mooier om die dingen in een array te zetten en dan achteraf de array te imploden, zoiets:

PHP:
1
2
3
4
5
6
7
8
9
function validateNotExisting($dbname, $table, $valueList)
{
  // ...
  $sqlFilters = array();
  foreach($valueList as $column => $value)
     $sqlFilters[] = $column . " = '" . mysql_real_escape_string($value) . "'";

 $sql = "SELECT COUNT(*) FROM " . $table . " WHERE " . implode(' AND ', $sqlFilters);
}


Trouwens, ik bedenk me iets. Als die projectie_id en dimensie_id samen uniek moeten zijn, zit er dan een UNIQUE constraint op? Of is het zelfs de primary key? Dat lijkt me een minimumvereiste voor zoiets.
Je hoeft dan niet eens per se zo'n check te doen als het zeldzaam is dat er dubbele waarden ingevoerd worden, want je insert-statement wordt dan toch niet door je database uitgevoerd.
Peter schreef op zaterdag 21 april 2007 @ 09:41:
en versnellen de boel ook nog eens redelijk, zeker als je veel strings gebruikt.
Nog een keer dan, het verschil is nihil. En dat is al heel lang zo, met php3 en misschien de eerste php4-versies maakte het inderdaad een beetje verschil, maar tegenwoordig is dat te verwaarlozen.

[ Voor 11% gewijzigd door ACM op 21-04-2007 09:48 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
ACM schreef op zaterdag 21 april 2007 @ 09:46:
Trouwens, ik bedenk me iets. Als die projectie_id en dimensie_id samen uniek moeten zijn, zit er dan een UNIQUE constraint op? Of is het zelfs de primary key? Dat lijkt me een minimumvereiste voor zoiets.
Je hoeft dan niet eens per se zo'n check te doen als het zeldzaam is dat er dubbele waarden ingevoerd worden, want je insert-statement wordt dan toch niet door je database uitgevoerd.
Die beperking zit ik inderdaad al op de tabel - die twee id's vormen samen de primary key.

Wat zijn jullie streng! :) Maar wel erg veel nuttige tips. Bedankt!

Acties:
  • 0 Henk 'm!

  • Skinkie
  • Registratie: Juni 2001
  • Laatst online: 09-06-2020

Skinkie

Op naar de 500

ACM schreef op vrijdag 20 april 2007 @ 23:29:
[...]

Dat heeft een dusdanig kleine invloed op de executietijd dat ie zeker met moderne php's (>4.1 ofzo) eigenlijk niet meer meetbaar is. Dus die tip is tamelijk loos.

Kwa code-duidelijkheid zou ik overigens niet een "toonbare" foutmelding uit de 'valideer-functie' laten rollen, maar eerder een boolean waarde oid.
Zet maar eens een 486 aan met PHP als je wat wilt meten. De TS vraagt om efficiëntere code, als hij het verschil tussen " " en ' ' niet weet, dan is de tip niet loos.

[ Voor 12% gewijzigd door Skinkie op 23-04-2007 16:24 ]

Steun Elkaar, Kopieer Nederlands Waar!


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

het verschil tussen ' en " zie ik meer als een micro optimalisatie, en vallen in het niet bij het optimaliseren van je algoritme, of bijvoorbeeld een mysql_num_rows vervangen door een count(*).

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

In een batch van enkele miljoenen runs heb ik de snelheid van het gebruiken van enkele en dubbele aanhalingstekens vergeleken.

De enige manier waarop "" langzamer is dan '' is in de constructie:
PHP:
1
echo "Tekst $variabele.";

De volgende maakten geen verschil:
PHP:
1
2
echo "Tekst ".$variabele;
echo 'Tekst '.$variabele;

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • Skinkie
  • Registratie: Juni 2001
  • Laatst online: 09-06-2020

Skinkie

Op naar de 500

CodeCaster schreef op maandag 23 april 2007 @ 16:51:
De volgende maakten geen verschil:
Je wilt dus zeggen dat PHP zonder een stringscan weet dat er geen $ in de string staat, knap.

Steun Elkaar, Kopieer Nederlands Waar!


Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Please jongens maak jullie niet druk over die enkele of dubbele quotes.

Je zal toch geen enkele miljoenen runs van zoiets doen?

Verder vind ik zelf persoonlijk de
PHP:
1
echo ("Test {$blaat}");
methode het prettigst en het overzichtelijkst in je code editor, een ander vindt het weer prettiger om alles met '.' aan elkaar te plakken, weer een ander met ',' weer een ander met sprintf en zo heeft ieder zn eigen voorkeur.

In real world maakt het geen ene reedt uit, en als het wel wat uitmaakt doe je iets gigantisch fout!

[ Voor 4% gewijzigd door SchizoDuckie op 23-04-2007 17:17 ]

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Skinkie schreef op maandag 23 april 2007 @ 16:54:
[...]

Je wilt dus zeggen dat PHP zonder een stringscan weet dat er geen $ in de string staat, knap.
Het zal niet exact tot in het oneindige achter de komma hetzelfde zijn, maar het geeft echter wel aan hoe futiel het verschil is en in dit geval kun je je beter laten leiden door de leesbaarheid ipv de enkel aangenomen (maar nauwlijks merkbare) efficientie verschillen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • sky-
  • Registratie: November 2005
  • Niet online

sky-

qn nna 👌

SchizoDuckie schreef op maandag 23 april 2007 @ 17:14:
Please jongens maak jullie niet druk over die enkele of dubbele quotes.

Je zal toch geen enkele miljoenen runs van zoiets doen?

Verder vind ik zelf persoonlijk de
PHP:
1
echo ("Test {$blaat}");
methode het prettigst en het overzichtelijkst in je code editor, een ander vindt het weer prettiger om alles met '.' aan elkaar te plakken, weer een ander met ',' weer een ander met sprintf en zo heeft ieder zn eigen voorkeur.

In real world maakt het geen ene reedt uit, en als het wel wat uitmaakt doe je iets gigantisch fout!
Goh, probeer je programma dan maar eens in PHP5/6 met ERROR_REPORTING(E_ALL) te runnen , geheid dat je een error krijgt. Variabelen _ALTIJD_ buiten quotes (single of double) halen.
PHP:
1
echo "Test ".$blaat;

don't be afraid of machines, be afraid of the people who build and train them.


Acties:
  • 0 Henk 'm!

  • Morax
  • Registratie: Mei 2002
  • Laatst online: 20:32
k8skaaay schreef op maandag 23 april 2007 @ 18:14:
[...]

Goh, probeer je programma dan maar eens in PHP5/6 met ERROR_REPORTING(E_ALL) te runnen , geheid dat je een error krijgt. Variabelen _ALTIJD_ buiten quotes (single of double) halen.
PHP:
1
echo "Test ".$blaat;
Nee hoor, dit is gewoon een valide manier om variabelen in een string te zetten hoor :)

What do you mean I have no life? I am a gamer, I got millions!


Acties:
  • 0 Henk 'm!

  • sky-
  • Registratie: November 2005
  • Niet online

sky-

qn nna 👌

Hmm, daar was ik niet van bewust.

Weer wat geleerd !

don't be afraid of machines, be afraid of the people who build and train them.


Acties:
  • 0 Henk 'm!

  • Morax
  • Registratie: Mei 2002
  • Laatst online: 20:32
k8skaaay schreef op maandag 23 april 2007 @ 18:58:
Hmm, daar was ik niet van bewust.

Weer wat geleerd !
En bij deze ook nog de officiele Bron (Kon ik net ff niet zo snel vinden :P)

What do you mean I have no life? I am a gamer, I got millions!

Pagina: 1