Gå til innhold

PHP- & MySQL-innføring: Kapittel 3


Anbefalte innlegg

Videoannonse
Annonse

Du nevner alternativ syntaks uten å nevne noen av de syntaksene som faktisk kan være fornuftige.

 

I noen sammenhenger er denne mer lesbar enn vanlig if-else:

if ($someAssertion)
 foo();
else
 bar();

 

Der har man spart 2 linjer og det kan, på de rette plassene, øke lesbarhet og forståelsen av koden.

 

En annen syntaks som er fin noen få ganger:

$niceWeather = true;
$var ($niceWeather ? 'Nice weather' : 'Bad weather');
// $var = 'Nice weather';

 

Den siste kalles terniary syntaks (Jeg vet ikke om noe norsk uttrykk).

 

Jeg vil anbefale å ikke bruke terniary så ofte, forhold deg til maks 72 tegn pr linje, går utsagnet over disse 72 tegnene ved bruk av terniary så bruk en annen syntaks.

Lenke til kommentar

Dette er mer et interessant faktum enn akkurat pirking.

Her er en liste over alle logiske operatorer i PHP5:

  • and - Er sann hvis begge uttrykkene stemmer
     
  • or - Er sann hvis minst ett av uttrykkene stemmer
     
  • xor - Er sann hvis ett av (men ikke begge) uttrykkene er sanne
     
  • && - Akkurat samme som and
     
  • || - Akkurat samme som or
     
  • ! - Er sann hvis uttrykket til høyre er usant

Dette er ikke sant, men stemmer dog nesten. AND og OR har lavere presidens (man kan forsåvidt si prioritering) som && og ||. Normalt vil man aldri merke dette, men i noen spesielle tilfeller kan man få uventede resultater om man bruker AND eller OR.

 

For å ta et konstruert tilfelle:

<?php
$a = -1;
$b = $a < 100 and $a > 0;
$c = ($a < 100 and $a > 0);
($d = $a < 100) and $a > 0;
echo '$b er '.intval($b).', $c er '.intval($c).' og $d er '.intval($d);
?>

Her vil man forvente at $b er det samme som $c, altså at output er "$b er 0, $c er 0 og $d er 1". Hvis du derimot faktisk kjører koden vil du straks oppdage at output er "$b er 1, $c er 0 og $d er 1" ... De aller, aller fleste vil nå si "HÆ?!? Hvorfor i h... skjer dette? :huh:". Grunnen til dette (for de fleste) overraskende resultatet ligger i at = har høyere presidens enn and og at "and $a > 0" aldri ble en del av uttrykket som settes lik $b.

 

<?php
$a = -1;
$b = $a < 100 && $a > 0;
$c = ($a < 100 && $a > 0);
($d = $a < 100) && $a > 0;
echo '$b er '.intval($b).', $c er '.intval($c).' og $d er '.intval($d);
?>

Setter vi derimot && inn for and får vi de resultatene som vi forventer, nemlig at $b er det samme som $c og outputen "$b er 0, $c er 0 og $d er 1"

 

Ut fra dette kan man lese at && og || bør foretrekkes fremfor AND og OR og/eller at det i tvilstilfeller er bedre å bruke for mange paranteser enn for få.

 

Edit: Hele presidenslisten i PHP finner man her :)

Endret av Ernie
Lenke til kommentar
En annen syntaks som er fin noen få ganger:

$niceWeather = true;
$var ($niceWeather ? 'Nice weather' : 'Bad weather');
// $var = 'Nice weather';

 

Den siste kalles terniary syntaks (Jeg vet ikke om noe norsk uttrykk).

 

 

"Ternær" er den vanlige betegnelsen på norsk. Og om man skal pirke litt, så er det vel strengt tatt operatoren ?: som er ternær og ikke syntaksen. En operator har et antall argumenter, gjerne kalt ariteten. Har den kun ett argument kalles den unær, har den to argumenter er den binær, og har den tre (som ?: har) så er den ternær :)

Lenke til kommentar
Gjest Slettet+6132
Hva er det du snakker om? Hvor står det "ellærs"? Kanskje Håvard har rettet det opp. :hmm:
Litt ned på siden står det:

 

EDIT: Eller, det var visst fiksa ... tror jeg.

Endret av Slettet+6132
Lenke til kommentar
"Ternær" er den vanlige betegnelsen på norsk. Og om man skal pirke litt, så er det vel strengt tatt operatoren ?: som er ternær og ikke syntaksen. En operator har et antall argumenter, gjerne kalt ariteten. Har den kun ett argument kalles den unær, har den to argumenter er den binær, og har den tre (som ?: har) så er den ternær  :)

6519781[/snapback]

 

Du har selvsagt helt rett. Jeg skrev dessuten feil, det er ternary, og ikke terniary, operator. Jeg tenker egentlig bare på det som en forkortet if-else-setning siden det er stort sett der man finner ternære operatører. Men rett skal være rett :)

Lenke til kommentar
Ut fra dette kan man lese at && og || bør foretrekkes fremfor AND og OR og/eller at det i tvilstilfeller er bedre å bruke for mange paranteser enn for få.

Nei, det er ikke bedre å bruke for mange parenteser enn for få.

 

Det kan føre til uoversiktlig kode og misforståelser.

 

La meg låne fra et eksempel som står i brukerkommentarene til PHP-manualen:

 

<?php
function my_print($a) { print($a); }
?>
<HR>
<?php
my_print (trim($var)=="") ? "empty" : "not empty";
?>
<HR>
<?php
print (trim($var)=="") ? "empty" : "not empty";
?>

Naivt sett skulle man kanskje tro at disse gjorde det samme. Det gjør de ikke.

 

Konklusjon: bruk parenteser kun der hvor det er nødvendig for å sikre at logikken fungerer slik du har tenkt.

 

Edit: Hele presidenslisten i PHP finner man her :)

Ja, denne burde alle som skal programmere i PHP lære seg utenat.

 

Kan noen putte den inn i artikkelen på et dertil egnet sted?

Lenke til kommentar

Har en liten kommentar til bruken av break, spesielt i switch-statements....

 

gjør det til en vane å alltid følge break med ett tall, vanligvis break 1;. Selv om break; fungerer, vil dette være en god kilde til fuckups, mye banning og riving i håret om man begynner å lage avanserte script. Hvorfor?

 

I avanserte script kan du få behov for å nøste flere løkker, for eksempel en switch-løkke inni en annen, en foreach-løkke inni en switch-løkke, eller omvendt, osv. break 1; angir at du bare skal hoppe ut av akkurat denne løkken, slik at den løkka som er utenfor fortsetter som vanlig. Skriver du derimot break; vil koden hoppe ut av den ytterste løkka, og mye kode som skulle vært kjørt blir aldri kjørt. Kan illustrere ett eksempel:

 

switch ($condition) {

  case "kjørdowhile":
     do {
        $c++;
        $cisf = $c+$annenting;
        if ($cisf == 450) {
          break;
        }
     while ($c < 500)
     $doit = "Denne koden blir nå ikke kjørt - fordi vi har hoppet ut av både do-while løkken og switch-løkken";
   break;
}
echo $doit; //hva tror dere brukeren får se her? Nettopp: ingenting...

 

Derfor, alle blivende PHP-geeks, lær dere dette først som sist: skriv alltid (kan ikke få understreket dette nok) ett tall (i de fleste tilfeller 1) etter break...:

switch ($condition) {

  case "kjørdowhile":
     do {
        $c++;
        $cisf = $c+$annenting;
        if ($cisf == 450) {
          break 1;
        }
     while ($c < 500)
     $doit = "Denne koden blir kjørt, og doit-variabelen får verdien sin";
   break 1;
}
echo $doit; //brukeren får output'en sin, og blir en stk blid og fornøyd PHP-programmerer...

Endret av ventle
Lenke til kommentar
Gjest Slettet+9018234

Sitepoint for å lære deg PHP og MySQL

 

takk.

 

Kommentar til artikkel: Vær konsis på hvor du bruker " og '. God kode-etikk tilsier at du bruker ' for variabler og " for strenger. Snakker av erfaring, og to store nettsteder som til daglig har svært mange besøkende.

 

Les også "The CakePHP Framework" angående sikkerhet og navnekonvensjoner for PHP, noe som er svært viktig: her

Endret av Slettet+9018234
Lenke til kommentar
Les også "The CakePHP Framework" angående sikkerhet og navnekonvensjoner for PHP, noe som er svært viktig: her

Tja.

 

Det nettstedet gir eksempelkode som er sårbar for XSS på servere hvor register_globals er påskrudd og glemmer av farene ved URL-enkodede strenger, feller som flere store kjente programvarepakker har hoppet rett uti.

 

Til stedets forsvar må det vel sies at de har linket til XSS-FAQen. :)

Lenke til kommentar

Konvensjoner er viktig men jeg kan ikke se at den artikkelen sier noe spesifikt om konvensjoner. Sitepoint er antageligvis det beste nettsted for de av oss som driver med webutvikling, men det kommer mest pga forumet.

 

Jeg foreslår at André legger ut et sett med rimelig standard konvensjoner som de som lærer php gjennom denne serien kan bruke.

En kikke på ZF (Zend Framework) kan kanskje være å anbefale også. Ikke på grunn av at det er så bra nå men det kommer veldig sannsynlig til å bli det største php-rammeverket om 1 år.

Lenke til kommentar

do-while blir det brukt semikolon etter hele greien, men vanligvis ikke etter if-else, while og for, slik som dette:

do {
 [kode]
} while ([uttrykk]);

while ([uttrykk]) {
 [kode]
}

if ([uttrykk]) {
 [kode]
} elseif ([uttrykk]) {
 [kode]
} else {
 [kode]
}

for ($i = 1; $i < 10; $i++) {
 [kode]
}

Men noen plasser har jeg sett at det har blitt brukt konsekvent etter alle fire, slik som dette:

do {
 [kode]
} while ([uttrykk]);

while ([uttrykk]) {
 [kode]
};

if ([uttrykk]) {
 [kode]
} elseif ([uttrykk]) {
 [kode]
} else {
 [kode]
};

for ($i = 1; $i < 10; $i++) {
 [kode]
};

Er det noen praktisk forskjell? Hva er mest riktig?

Lenke til kommentar
Men noen plasser har jeg sett at det har blitt brukt konsekvent etter alle fire, slik som dette:

 

...

 

Er det noen praktisk forskjell? Hva er mest riktig?

Det første eksempelet ditt er mest riktig, fordi det ikke introduserer ekstra, unødvendig kode i forhold til det andre.

 

Både PHP og C er programmeringsspråk som tilgir deg ekstra semikolon og mellomrom, du kunne like gjerne skrevet:

 

 

if ($i > 1) {
   echo "foo";

  ;;     ;;
      ;
      ;
  ;       ;
   ;;;;;;;

}    ;;;

Det gjør altså ingen forskjell for utførelsen av koden, men det er totalt unødvendig.

Lenke til kommentar
Nei, det er ikke bedre å bruke for mange parenteser enn for få.

 

Selvfølgelig er det det, for mange paranteser vil kunne bedre lesbarhet, for få vil gi deg bugs og ulumskheter.

 

 

Det kan føre til uoversiktlig kode og misforståelser.

 

I langt mindre grad enn for få.

 

La meg låne fra et eksempel som står i brukerkommentarene til PHP-manualen:

 

<?php
function my_print($a) { print($a); }
?>
<HR>
<?php
my_print (trim($var)=="") ? "empty" : "not empty";
?>
<HR>
<?php
print (trim($var)=="") ? "empty" : "not empty";
?>

Naivt sett skulle man kanskje tro at disse gjorde det samme.  Det gjør de ikke.

 

Som ikke har med intern evaluering av uttrykk å gjøre, men av at print er en language construct og ikke en vanlig funksjon. Det er en ren misforståelse av hvordan print fungerer. Det er ikke noe problem å bruke paranteser for å FORVIRRE folk om du virkelig vil det, men god og fornuftig (og mer enn NØDVENDIG) bruk av parenteser er langt viktigere enn å lære noen som helst til å tro at man skal prøve å bruke færrest mulig. Det å stole på evalueringsrekkefølge og presedens er en forferdelig ting, spesielt når man veksler mellom mange språk over kort tid.

 

I samme åndedrag vil jeg også si at det er langt mer lesbart å skrive

 

if ()

{

 

}

else

{

 

}

 

enn samme statement uten { }. (og plassér de for all del på egen linje! Det øker navigasjonshastigheten din på kodelesing!)

 

Jeg vil også slå et slag for å ikke bruke do { } while-syntax, ettersom det reduserer lesbarheten ved å plassere avgjørelsen av hvorvidt løkka skal fortsette på et annet sted enn det som fornuftig lesbarhet tilsier.

Lenke til kommentar
I samme åndedrag vil jeg også si at det er langt mer lesbart å skrive

 

if ()

{

 

}

else

{

 

}

 

enn samme statement uten { }. (og plassér de for all del på egen linje! Det øker navigasjonshastigheten din på kodelesing!)

 

Jeg vil også slå et slag for å ikke bruke do { } while-syntax, ettersom det reduserer lesbarheten ved å plassere avgjørelsen av hvorvidt løkka skal fortsette på et annet sted enn det som fornuftig lesbarhet tilsier.

6539417[/snapback]

Støtter at do-while-syntaks ikke bør brukes av de grunner du nevner, men når det kommer til if-else er det helt individuelt hva som er mest lesbart.

For meg er ...:

if () {
}
else {
}

... mest lesbart og gjør det enklest for meg å lese kode.

Lenke til kommentar
Nei, det er ikke bedre å bruke for mange parenteser enn for få.

 

Selvfølgelig er det det, for mange paranteser vil kunne bedre lesbarhet, for få vil gi deg bugs og ulumskheter.

For mange parenteser kan også skape bugs og ødelegge lesbarheten, som vist i eksempelet jeg gjenga nedenfor. Poenget mitt var å forsøke å fortsette å bruke terminologien til han jeg svarte på, som antydet at "for få" var å ikke bruke parenteser når presedensreglene ellers var greie. Beklager at jeg ikke gjorde det klart, jeg ser jo at det jeg skrev ser helt idiotisk ut nå. :)

 

 

Men, altså:

 

Ville du stolt på resten av logikken i et program som inneholder dette?

if (($a && $b) || $c)

Det ville ikke jeg!

 

... *snip eksempelet mitt*

 

Som ikke har med intern evaluering av uttrykk å gjøre, men av at print er en language construct og ikke en vanlig funksjon. Det er en ren misforståelse av hvordan print fungerer.

Men det illustrerer poenget ypperlig for hvordan man kan forvirre folk fordi man selv ikke forstår når man skal bruke parenteser og ikke.

 

Det er ikke noe problem å bruke paranteser for å FORVIRRE folk om du virkelig vil det, men god og fornuftig (og mer enn NØDVENDIG) bruk av parenteser er langt viktigere enn å lære noen som helst til å tro at man skal prøve å bruke færrest mulig. Det å stole på evalueringsrekkefølge og presedens er en forferdelig ting, spesielt når man veksler mellom mange språk over kort tid.

Her er jeg uenig.

 

Man skal ikke bruke samme kodestil på tvers av programmeringsspråk; det er dårlig programmeringsskikk, og fører til mer forvirring enn det er verdt.

 

Det kan også skape tvil om hvorvidt programmereren faktisk vet hva han driver på med (for de som bryr seg om slikt).

 

Nei, ikke legg på ekstra syntaks i forhold til det som kreves i henhold til kodestandardene der du jobber, eller i forhold til det som er normen i programmeringsspråket. Bruk gjerne de alternative syntaksene som er tilgjengelig, men ikke lat som om ekstra parenteser, ekstra krøllklammer eller liknende faktisk gjør noe.

 

 

Unntak: hvis du skriver kode for MySQL, så må du være forberedt på at presedensreglene for SQL endrer seg i en ny patchlevel og ikke bare i en ny versjon ...

 

Further changes in join processing were made in 5.0.12 to make MySQL more compliant with standard SQL. These charges are described later in this section.

(MySQL Join Syntax)

 

 

I samme åndedrag vil jeg også si at det er langt mer lesbart å skrive

 

if ()

{

 

}

else

{

 

}

 

enn samme statement uten { }. (og plassér de for all del på egen linje! Det øker navigasjonshastigheten din på kodelesing!)

Her er det rom for personlig smak eller lokale kodestandarder.

 

Folk som kommer fra et tradisjonelt Unix-miljø vil trives mer med den varianten som Findus nevner.

 

Det endrer ikke nevneverdig på lesbarheten.

 

Et av standardargumentene mot krøllklamme på samme linje som if, elseif eller else, er at det ved bruk av svært lange testbetingelser i if() og elseif() kan bli vanskelig å finne igjen den klammen, og at programmer som VI gjerne viser deg hvor klammen du "matcher" var og at det kan være forvirrende at de ikke er på samme kolonne.

 

1) Ikke bruk så lange testbetingelser; det gjør koden vanskelig å lese.

2) Det er lov å avvike kodestandarden litt for å gjøre koden lesbar akkurat der.

 

Jeg vil også slå et slag for å ikke bruke do { } while-syntax, ettersom det reduserer lesbarheten ved å plassere avgjørelsen av hvorvidt løkka skal fortsette på et annet sted enn det som fornuftig lesbarhet tilsier.

Det der er igjen et spørsmål om smak og programmeringsfilosofi.

 

Motargumentet er at do-while gjør det helt klart at det som står mellom krøllklammene vil bli utført minst en gang. Hvis du bruker en vanlig while istedenfor, så må den som leser koden både lese og tolke betingelsen i while() for å vite hvorvidt dette skjer eller ikke. Dersom ikke verdien av innholdet i while() er opplagt ut fra de nærliggende linjene i koden, så vil dette medføre mye merarbeid. I tillegg kan det være mer jobb å vedlikeholde koden.

 

Personlig foretrekker jeg også å unngå do-while, men jeg ser altså at det kan være like nyttig som f.eks.:

print "Yeeha!";

while ($somevar && ($othervar || $anothervar)) {
   print "Yeeha!";
}

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...