Programming and Webscripting FAQ: Algemeen
Wat FAQ's op een rij
- Beveiliging van websites
Met dank aan ACM
- Openmaken van exe's, mag dat?
Over decompileren e.d.
Met dank aan cutter - Hoeveel kan ik vragen voor ...?
Met dank aan MrX
- Debuggen: hoe doe ik dat?
- Richtlijnen voor nette code
In MSDN staat nog een stuk over Writing Solid Code. Zeer zeker de moeite waard om even door te nemen. (!)
- Waar vind ik RFC's en protocol standaarden?
Als je scripts of programma's zoekt ...
- codebase
Hier kun je code(snippets) vinden voor allerlei talen en zelf ook code plaatsen
- hotscripts.com
Hier kun je kant en klare scripts vinden voor allerlei verschillende toepassingen
- SourceForge
Open source projecten op allerlei gebieden
Links voor programmeurs
- pdaprogrammeren.nl
Een site toegewijd aan het programmeren van PDA's
- programmersheaven.com
- programmingtutorials.com
- Developersdex
Links voor web-scripters
Boeken
Algemeen
- An Introduction to Formal Languages and Automata
Door: Peter Linz
ISBN: 0763714224
Jones & Bartlett Pub - Code: The Hidden Language of Computer Hardware and Software
Door: Charles Petzold
ISBN: 0735611319
Microsoft Press - Computer Architecture: a Quantitative Approach
Door: David Patterson, John Hennessy
ISBN: 1558603727
Morgan Kaufmann Publishers, Inc - Computer Networks
Door: Andrew Tanenbaum
ISBN: 0130661023
Prentice Hall - Computer Networks and Internets
Door: Douglas E. Comer
ISBN: 0130914495
Prentice Hall - Gestructureerde Computerarchitectuur
Door: Andrew S. Tanenbaum
ISBN: 90 395 1087 3
Academic Service
Algoritmen
- Datastructuren en algoritmen in 24 uur
Door: -
ISBN: 90 395 1436 4
- - Introduction to Algorithms (2nd ed.)
Door: Thomas H. Cormen (Editor), Charles E. Leiserson, Ronald L. Rivest, Clifford Stein
ISBN: 0262032937
MIT Press
Ontwerp en software-architectuur
- Patterns of Enterprise Application Architecture
Door: Martin Fowler, David Rice, Matthew Foemmel, Edward Hieatt, Robert Mee, Randy Stafford
ISBN: 0321127420
Addison Wesley Professional - Code Complete: A Practical Handbook of Software Construction
Door: Steve C McConnell
ISBN: 1556154844
Microsoft Press - Design Patterns Elements of Reusable Object-Oriented Software
Door: Erich Gamma, Richard Helm, Ralph Johnson en John Vlissedes
ISBN: 0201634988
Addison Wesley Publishing Company - Pattern Hatching: Design Patterns Applied (Software Patterns Series)
Door: John Vlissides
ISBN: 0201432935
Addison Wesley Publishing Company - Pattern-Oriented Software Architecture, Volume 1: A System of Patterns
Door: Frank Buschmann, Hans Rohnert, Michael Stal, Peter Sommerlad, Regine Meunier
ISBN: 0471958697
John Wiley and Sons Ltd - Pattern-Oriented Software Architecture, Volume 2, Patterns for Concurrent and Network Objects
Door: Douglas Schmidt, Frank Buschmann, Hans Rohnert, Michael Stal
ISBN: 0471606952
John Wiley and Sons Ltd - Programming Pearls (2nd Edition)
Door: Jon Bentley
ISBN: 0201657880
Addison Wesley Publishing Company - Refactoring
Door: Martin Fowler
ISBN: 0201485672
Addison Wesley Publishing Company - The Art Of Computer Programming delen 1-3
Door: Donald Ervin Knuth
ISBN: 0201485419
Addison Wesley Publishing Company - The Practice of Programming
Door: Brian Kernighan, Rob Pike
ISBN: 020161586X
Addison Wesley Publishing Company - Toward zero-defect programming
Door: Allan Stavely
ISBN: 0-201-38595-3
Addison Wesley Publishing Company
Openmaken van exe's en decompilen
Dit is in principe gewoon illegaal (net als cracks, passes, warez etc) en voor ons daarom niet/nauwelijks na te gaan of er wel of niet illegaal gedrag getoond wordt. Daarom hebben we besloten het als illegaal te beschouwen en zijn dit soort topics niet gewenst.
cutter zei hierover het volgende:
Doordat artikel 6 van de Softwarerichtlijn en artikel 45m Aw stellen dat decompilatie onder omstandigheden is toegestaan, is iedere decompiler per definitie inzetbaar voor zowel wettelijk toegestaan, als voor inbreukmakend gebruik van software. De overweging bij de Auteursrechtrichtlijn geeft aan dat decompilers niet verboden zijn. Dat kan impliceren dat de zinsnede 'uitsluitend bestemd om de ongeoorloofde verwijdering of ontwijking van softwarebeveiliging te vergemakkelijken' in de Softwarerichtlijn, betekent dat omzeilingsmiddelen alleen onder de bepaling vallen, indien zij uitsluitend bestemd zijn om inbreukmakende handelingen te faciliteren. Wanneer zij tevens op basis van het auteursrecht niet te verbieden gebruik van software mogelijk maken, vallen ze er niet onder.
Decompilen mag voor het tot stand brengen van intercompatibiliteit, zorgen dat proggies (interfaces) met elkaar kunnen communiceren. Dat mag alleen als je zonder het decompileren de intercompatibiliteit niet tot stand kan brengen en je het proggie rechtmatig in je bezit hebt.Of je nu voor studie mag decompileren weet ik niet. Je mag wel proberen de achterliggende gedachten te achterhalen door het laden, in beeld brengen, de uitvoering, de transmissie of de opslag van het programma.Er wordt eigenlijk niet meer gesproken van decompileren maar van 'omzeilen van een technische voorziening' in de voorstellen voor een nieuwe auteurswet. Onder omstandigheden mag dat.
Kern van de door de commissie voorgestelde bepaling is dat de wetgever ingrijpt op het moment dat de betekenis en ratio van de beperkingen onder artikelen 16 (ten behoeve van onderwijs), 16b en 16c (privé-kopiëren), 16h (reprografisch verveelvoudigen), 16n (verveelvoudigen voor preserveringsdoeleinden), 17b (efemere vastleggingen door omroeporganisaties) en 22 (gebruik in het kader van gerechtelijke en bestuurlijke procedures) in het gedrang komt.
Dit zijn een aantal situaties wanneer decompilen zou mogen, maar die moeten nog verder uitgewerkt worden in een op de nieuwe auteurswet gebaseerde aanvullende regeling (ook wel Algemene Maatregel van Bestuur (AMVB) genoemd)
2. Tips bij debuggen
Met dank aan MrX
Het komt vaak voor dat er vragen gesteld worden opgelost hadden kunnen worden door een beetje debuggen. Ontluizen, zou je 't kunnen noemen. Vaak weet je niet precies waar de fout zit, maar wel ongeveer. Om achter de fout te komen kun je het beste even dit stukje als handleiding gebruiken bij het debuggen.
Wat gaat er fout?
Foutmeldingen, waarschuwing, etcetera. Waarschuwingen heb je nooit teveel. Dit betekent o.a. dat het bij C++ compilers handig is (bijvoorbeeld gcc of g++) met een Wall (warn all) parameter te werken, bij Perl met een use strict; en te parsen met de -w parameter en bij PHP met error_reporting op E_ALL
Eveneens kan het handig zijn gebruik te maken van software die je de mogelijkheid geeft stap voor step (step) door je code heen te wandelen en zelf debug-informatie te leveren door gebruik te maken van watches (wat gebeurt er met bepaalde variabelen?)
Als dergelijke software niet beschikbaar is in jouw geval kan het handig zijn zelf dergelijke watches of step-by-step's te schrijven. Bij PHP kan dit heel eenvoudig door trigger_error ()-aanroepen of eventueel gebruik te maken van die() of exit() in debugfase
Als je bepaalde foutmeldingen niet begrijpt, kan het handig zijn de foutmelding gewoon te copy-pasten naar google of de search van GoT en even te kijken wie dergelijke foutmeldingen ook had. Mensen geven over het algemeen bij hun problemen wel de foutmeldingen op; zodoende kan je er ook altijd op zoeken
Wat zijn de omstandigheden?
Ga na welke handelingen en stukken code de fout(en) en waarschuwing(en) hebben veroorzaakt. Bij waarschuwingen en foutmeldingen wordt bijna altijd wel een regelnummer en offset gegeven. Dan is het redelijk triviaal de fouten op te lossen. Bij Java en veel C++ compilers komt er zelfs een stacktrace bij kijken zodat je kan zien wat de allereerste oorsprong van de foutmelding of waarschuwing is.
Reproduceer de foutieve code
Isoleer het stuk code wat de fout veroorzaakt, door alle code die er geen invloed op heeft eventueel te commenten of tijdelijk te verwijderen. In sommige gevallen is het handig om enkel het stuk code te compileren wat de fout veroorzaakt, zodat je daarover debuginformatie naar je scherm kan printen.
Let, wanneer je het foutieve stuk code uitvoert vooral op
- waarden van relevante variabelen
- calls naar externe functies/objecten/etc., die evt. onvoorspebaar of incorrect gedrag vertonen
- niet afgevangen condities (Null waarden, geen records gereturned, negatieve waarden, verkeerd type waarden, etc.)
- syntax vergissingen (bijv. "=" gebruiken als vergelijkingsoperator waar je "==" zou moeten gebruiken)
- correctheid van (loop) condities ('out of bounds' problemen, '>' dat '>=' zou moeten zijn, etc.)
SQL, geval apart
Fouten of foutmeldingen bij het gebruik van SQL heeft in 9 van de 10 gevallen te maken met het feit dat de query niet goed opgebouwd wordt.
Wanneer je een query doet aan een SQL server en je krijgt onverwachte resultaten terug, dan betekent dat meestal dat je query een syntax error of iets dergelijks bevat. Geef de SQL server ook de kans foutmeldingen te geven. Negeer foutmeldingen van de SQL server nooit. Als je dan niet in 1 oogopslag ziet wat het probleem is, open dan een directe connectie naar de database en voer de query handmatig uit en speel ermee tot die wel goed is voordat je de code aanpast.
Connecties tussen systemen
Als je van deel A naar deel B een connectie maakt (COM call, message queue, HTTP call, CORBA call, etc), zorg dan dat je direct voor de uitgang van systeem A en na de ingang bij systeem B alle waarden logt, zodat je precies kan vergelijken of deze overeenkomen en je zeker weet in welk deel het probleem zit.Als je het probleem nu nog niet ziet of kunt oplossen, isoleer dan precies de regel code die de fout triggert en haal er een buitenstaander bij, die een frisse blik op jouw code kan werpen.tnx MrX voor dit stukje.
Meer informatie
Meer informatie kun je vinden in dit topic: [ALG] Hoe pakt een programmeur debuggen aan?
3. Richtlijnen voor nette code
Het is een goede gewoonte om jezelf wat conventies aan te leren als het gaat om het netjes opschrijven van code. Dit onderdeel geeft je wat richtlijnen, die je kunnen helpen bij het leesbaarder maken van je code.
De voorbeelden die wat minder leesbaar zijn, zijn Fout gemarkeerd en de leesbare voorbeelden Goed. Dit betekent overigens niet dat de foute manier altijd de slechtste manier is en de goede manier altijd de beste. Er zijn altijd meerdere wegen die naar Rome leiden. Onthoud dus dat het richtlijnen zijn en niet perse de manier
Zet commentaar bij non-triviale code
Je code moet leesbaar zijn voor anderen. Dit betekent dat je in normaal Engels, (of normaal Nederlands, wat je liever hebt), bij je code neerzet wat daar de bedoeling is, als dat niet al uit de code opzich spreekt. Ook kan dit bij het debuggen van pas komen, als je een stuk code zoekt wat bepaalde logica uitvoert. Snel zoeken door code heen gaat nou eenmaal makkelijker op gestructureerd commentaar, dan op de taal zelf.
Naarmate je meer een ervaren programmeur wordt, wordt het lezen van code ook gemakkelijker. Toch geeft dat je geen vrijbrief om je code vrij te laten van commentaar. Je maakt het namelijk ook de mensen die later je code nog 's moeten lezen een stuk gemakkelijker.
Voorbeeld
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| /** * interface MijnInterface * * Functie: geeft een voorbeeld van hoe je je code wat commentaar kan geven */ public interface MijnInterface { /** * Method sjakieSpef * * Parameters: * String woei bladie bladie blah * MijnClass yay yack yack yadayada * * Returns: String containing the spef of Sjaak */ protected String sjakieSpef ( String woei, MijnClass yay ) { String return_value = ""; // ... return return_value; } // etcetera } |
Schrijf code niet altijd zo kort mogelijk
Fout
1
2
3
4
| String s = "Target" + + (this.i>l&&this.i<u? not:) + in range; System.out.println(s); |
Goed
1
2
3
4
5
| if ( this.duidelijkeNaam < upperLimit && this.duidelijkeNaam > lowerLimit ) { System.out.println( "Target in range" ); } else { System.out.println ( "Target not in range" ); } |
Inspringen
Spring na { in en spring terug voor de bijbehorende }. In Basic-achtige talen, betekent dat inspringen na een IF en terugspringen voor de bijbehorende END IF, etcetera.
Fout
1
2
3
| if ( conditie ) { voeruit()}else {if(conditie2){ voeruit2();}} |
Goed
1
2
3
4
5
6
7
| if ( conditie ) { voeruit (); } else { if ( conditie2 ) { voeruit2 (); } } |
Bij geneste functieaanroepen kun je vaak beter ook inspringen
1
2
3
4
5
6
7
| this.myFirstFunction ( argument, argument, That.hisFirstFunction ( anotherArgument ) ); |
Als je aan het debuggen bent, kan het nog wel eens van pas komen je code even op die manier uit te lijnen zodat je zeker weet dat de haakjes goed staan, oftewel, dat de nesting klopt.
Naamgeving
De naamgeving binnen code is een van de belangrijkste dingen voor het onderhoudbaar houden van je code.
Een naam is niet gauw te lang, hij is wel gauw te kort. Het is een hele goede gewoonte om in namen goed te beschrijven wat het voor iets is. Vaak kun je dit door bepaalde conventies te hanteren al wel vastleggen. Zo is het gebruikelijk om objecten en classnames met een Hoofdletter te laten beginnen en CamelCased te schrijven (elke nieuw woord in de naam laten beginnen met een hoofdletter):
1
2
3
4
| class MyClass { public MyClass () { } } |
Bij methode en propertynamen is het gebruikelijk ook te camelCasen maar met een kleine letter te beginnen:
1
2
3
4
5
6
7
8
9
10
| class MyClass { private int isNoValue; public MyClass () { this.isNoValue = null; } public void doNothing () { } } |
In C++ en C heb je, iets meer dan in Java, vaak te maken met de scope van variabelen. Er is wat voor te zeggen om in je variabelenamen op te nemen wat de scope van de variabele is. Ook kan het handig zijn om het type variabele in de naam op te nemen.
1
2
3
4
5
6
7
8
9
10
11
12
| const int c_myConstantInt; int g_myGlobalInt; class MyClass { private int p_myPropertyInt; public MyClass ( int ) {} } MyClass::MyClass ( int a_myArgumentInt ) { int l_myLocalInt; } |
Ook heb je in C en C++ te maken met functienamen die niet tot een class behoren. 't Kan geen kwaad onderscheid te maken in de wijze van schrijven van de functies enerzijds en de methoden anderzijds.
1
2
3
4
5
6
| int do_something () { // ... } int MyClass::doSomething () { } |
HTML en SQL in PHP
Bij PHP maakt het verschil wat de insteek is van je PHP document. Vele PHP-programmeurs maken verschil tussen de template-georienteerde pagina's enerzijds en de logica-georienteerde pagina's anderzijds. Probeer HTML zo veel mogelijk buiten de logica te houden en de logica zoveel mogelijk buiten de templates.
Bij template-georienteerde pagina's kun je op de volgende manier te werk gaan:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| <?php foreach ( $news_items as $news_item ) { ?> <div class="news-item"> <h1><?php echo htmlentities ( $news_item [ 'title' ] ); ?></h1> <div class="content"> <?php echo $news_item [ 'content' ]?></h1> </div> <?php foreach ( $menu_item [ 'references' ] as $reference ) { ?> <?php echo $reference [ 'date' ]; ?> <a href="news_item.php?id=<?php echo $reference [ 'reference_id' ];?>"> <?php echo $reference [ 'reference_title' ]; ?> </a> <br /> <?php } // end foreach references ?> </div> <?php } // end foreach news_items ?> |
Je ziet hier dat de nadruk op de HTML ligt en niet op de PHP. Overigens kun je voor dergelijke dingen ook (andere) template-engines gebruiken.
Bij logica georienteerde pagina's kun je beter PHP als uitgangspunt nemen. Let op dat je ook SQL statements uitlijnt. Dat zijn vaak onleesbare lappen code, die echt wel uitlijning verdienen.
In dit voorbeeld prepareert de logica in de PHP een array $news_items, om aan de template van hierboven te voldoen. Vaak is het voor de onderhoud van je code beter om op een dergelijke manier de logica van de layout te scheiden, vandaar dit ik 't even wat uitgewerkt heb.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
| <?php // Connect to local database 'drm' mysql_connect ( 'localhost', 'drm', 'myl33tp4ssw0rd' ); mysql_select_db ( 'drm' ); // Create query: // select all public news items from `news_item`, including // their public references from table `news_item_reference` $query = ' SELECT `news_item`.`news_item_id`, `news_item`.`title`, `news_item`.`content`, DATE_FORMAT(\'%d-%m-%Y\', `news_item`.`date_created`) AS `date`, `news_item_reference`.`news_item_left` IS NOT NULL AS `has_references`, `reference`.`news_item_id` AS `reference_id`, `reference`.`title` AS `reference_title` FROM `news_item` LEFT JOIN `news_item_reference` ON( `news_item`.`news_item_id` = `news_item_reference`.`news_item_id_left` ) INNER JOIN `news_item` AS `reference` ON( `news_item_reference`.`news_item_id_right` = `reference`.`news_item_id` ) WHERE `news_item`.`is_public`=\'true\' AND `reference`.`is_public`=\'true\' ORDER BY `news_item`.`date_created` DESC, `reference`.`date_created` DESC '; // perform query $news_items_result = mysql_query ( $query ); // initialize array to hold all news items $news_items = array (); // holds the id of the last fetched newsitem. $last_news_item_id = -1; // holds the currently fetched newsitem. $current_news_item = false; // fetch all newsitems from database while ( $news_item_row = mysql_fetch_assoc ( $news_items_result ) ) { // if this item is a new news item in the set: if ( $news_item_row [ 'news_item_id' ] != $last_news_item_id ) { $last_news_item_id = $news_item_row [ 'news_item_id' ]; // does not apply to the first iteration: if ( $current_news_item ) { // add the current item to the set $news_items []= $current_news_item; } // create new news_item $current_news_item = array ( 'title' => $news_item_row [ 'title' ], 'content' => $news_item_row [ 'content' ], 'date' => $news_item_row [ 'date' ], 'references' => array (), ); } // relation IS NOT NULL clause from query if ( $news_item_row [ 'has_references' ] ) { // add references to the current newsitem $current_news_item [ 'references' ] []= array ( 'reference_title' => $news_item_row [ 'reference_title' ], 'reference_id' => $news_item_row [ 'reference_id' ] ); } } include ( './tpl/template.news_item.php' ); |
[ Voor 158% gewijzigd door NMe op 18-08-2005 23:58 ]
Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz