The ABSOLUTE basics of Web Development
Published 11 months ago on July 28, 2023

What’s up folks, this post is absolutely packed full of information relating to web development environments in general and specifically PHP and apache. Feel free to skip to whatever section(s) interest you!

The Pre Rant
What Is A Website?
The Web Page
Before And After The Server
File Extensions Matter
File Extensions: A Common Problem
The Web Server
You Need A Server
Setting Up Local Server
Http Request Methods
Typical File Types
Index Dot What?!
Front-end vs Back-end
The Summary

The Pre-rant

I’m part of an online programming community that likes to help others with programming problems. Whether you’re on the fence about whether or not web development is really programming or just coding (🤯), there are tonnes of people who help others just because they can. There are two incredibly frustrating issues that we face daily, however.

chatGPT is the first, people will come in and ask for help with some code that they got from chatGPT, they don’t understand at all, and didn’t write a single character of. We had a guy a while back asking why his text was being printed on two lines, his text was this:


If that’s you, you have got to take a step back. Don’t use chatGPT to learn to program, it just regurgitates crap that it was once fed and it may well be correct, but it doesn’t help you to learn, and it’s not fair to expect others to explain and/or fix random AI generated code.

Anyway, I digress, we’re here to talk about web development!

The second frustrating issue is when somebody has decided to start learning HTML, JS, PHP, or whatever it may be, but have completely skipped the foundations of web development. They know nothing of servers and file types, and wonder why their PHP file at file:///Users/tdc/web-dev/index.php is just showing PHP code and not executing it or their .html file just shows PHP code.

and please don’t misunderstand me. I’m not slating beginners at all, we’ve all been there, its okay. I’m just trying to fill a gap that people often overlook.

So I won’t be discussing any actual code today, we’re going to talk about the general flow of web development, common file types, servers and server structure.


What IS a website?

This is a borderline infinitely technical question, there are IP addresses, DNS servers, web servers, proxies and the list goes on. But for today’s purpose, a website is simply a series of web pages that are delivered from a web server to your browser. So, what is a web page?

The web page

A web page usually consists of HTML, CSS and JavaScript. You visit a particular URL in your browser and that action requests the web server at the other end of the internet for the contents of a particular web page. Let’s say we visited Google, everybody knows Google. We type in our browser address bar and the request is sent to one of their many servers and it returns the contents of their home page. Let’s assume their home page is just a HTML page for now. It almost certainly isn’t, but let’s assume that it is.

info iconThe GET request

This is a HTTP GET request. We’re not sending any data, we’re just asking for the contents of a web page. So, we visit and google returns ‘index.html’ which will contain the HTML and CSS required to show you this:

Screenshot of google

Of course, that’s a pretty picture. What your browser gets is this:

<!doctype html><html itemscope="" itemtype="" lang="en-GB"><head><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"><meta content="/images/branding/googleg/1x/googleg_standard_color_128dp.png" itemprop="image"><title>Google</title><script nonce="4KJzuMY6meDuiXxn_sgGfQ">(function(){var _g={kEI:'k2a-ZKXDG7eyqtsPzbmq6AY',kEXPI:'0,793344,566065,6059,206,4804,2316,383,246,5,1129120,1748,1576742,16115,28684,22430,1362,284,12035,17580,4998,17075,35733,5583,2891,4140,8220,76795,230,1014,1,16916,2652,4,1528,2304,42125,13660,4437,9358,13204,6675,7596,1,42154,2,16737,3533,19491,5679,1021,31122,4568,6258,23418,1252,5835,19300,7484,11407,15675,8155,7381,2,15968,872,7830,11805,6,1922,9779,8213,14695,13362,6189,20199,927,19305,11259,8947,8377,18960,579,1089,2218,1517,3030,6110,9706,1804,7734,2738,2884,9481,10260,10958,3027,1635,2170,1071,4706,5893,1146,8276,3437,3052,4862,8847,549,7484,3,1271,2041,372,1178,5210368,35,17,8797901,3311,141,795,19735,1,303,44,6988,13,22,4,7,6,10,296,82,3,3,21,21,9,2,51,51,7,51,70,14,5,4,17,60,23942667,397,182,2769589,1273939,14297,2375,29032,3918,1406990,23763126,1568,2739,1049,2565,1022,2945,642,574,3366,882,1082,835,266,696,335,962,99,198,589,499,1016,776,650,24,872,913,1,1076,325,1955,219,540,515,13,243,495,242,752,476,2158,321,86,386,553,244,801,2346,1124,483,3,1225,975,1837,215,5,823,53,4,128,79,325,8,1315,453,690,76,1060,285,607,43,1007,1137,1,2,693,78,646,87,671,257,28,135,46,252,320,237,358,1,816,119,13,2,69,257,35,299,3,391,1354,2,73,1128,1004,904,3,55,163,15,150,196,224,348,172,118,465,1,3,227,579,2,880,17,675,304,98,545,32,76,246,552,293,486,3,79,97,31,386,1293',kBL:'_RjE',kOPI:89978449};(function(){var a;(null==(;}).call(this);})();(function(){'webhp';google.kHL='en-GB';})();(function(){ var h=this||self;function l(){return void 0! 0!!};var m,n=[];function p(a){for(var b;a&&(!a.getAttribute||!(b=a.getAttribute("eid")));)a=a.parentNode;return b||m}function q(a){for(var b=null;a&&(!a.getAttribute||!(b=a.getAttribute("leid")));)a=a.parentNode;return b}function r(a){/^http:/i.test(a)&&"https:"===window.location.protocol&&("a"),!1,{src:a,glmm:1}),a="");return a} function t(a,b,c,d,k){var e="";"&ei=")&&(e="&ei="+p(d),"&lei=")&&(d=q(d))&&(e+="&lei="+d));d="";var"&cshid=")&&"slh"!==a,f=[];f.push(["zx",]);h._cshid&&g&&f.push(["cshid",h._cshid]);c=c();null!=c&&f.push(["opi",c.toString()]);for(c=0;c<f.length;c++){if(0===c||0<c)d+="&";d+=f[c][0]+"="+f[c][1]}return"/"+(k||"gen_204")+"?atyp=i&ct="+String(a)+"&cad="+(b+e+d)};m=google.kEI;google.getEI=p;google.getLEI=q;{return null};google.log=function(a,b,c,d,k,e){e=void 0===e?l:e;c||(c=t(a,b,e,d,k));if(c=r(c)){a=new Image;var g=n.length;n[g]=a;a.onerror=a.onload=a.onabort=function(){delete n[g]};a.src=c}};google.logUrl=function(a,b){b=void 0===b?l:b;return t("",a,b)};}).call(this);(function(){google.y={};[];google.x=function(a,b){if(a)var;else{do c=Math.random();while(google.y[c])}google.y[c]=[a,b];return!1};{};google.lm=[];google.plm=function(a){google.lm.push.apply(google.lm,a)};google.lq=[];google.load=function(a,b,c){google.lq.push([[a],b,c])};google.loadAll=function(a,b){google.lq.push([a,b])};google.bx=!1;google.lx=function(){};}).call(this);google.f={};(function(){ document.documentElement.addEventListener("submit",function(b){var a;if({var c=a.getAttribute("data-submitfalse");a="1"===c||"q"===c&&!a.elements.q.value?!0:!1}else a=!1;a&&(b.preventDefault(),b.stopPropagation())},!0);document.documentElement.addEventListener("click",function(b){var a;a:{for(;a&&a!==document.documentElement;a=a.parentElement)if("A"===a.tagName){a="1"===a.getAttribute("data-nohref");break a}a=!1}a&&b.preventDefault()},!0);}).call(this);</script><style>#gbar,#guser{font-size:13px;padding-top:1px !important;}#gbar{height:22px}#guser{padding-bottom:7px !important;text-align:right}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}@media all{.gb1{height:22px;margin-right:.5em;vertical-align:top}#gbar{float:left}}a.gb1,a.gb4{text-decoration:underline !important}a.gb1,a.gb4{color:#00c !important}.gbi .gb4{color:#dd8e27 !important}.gbf .gb4{color:#900 !important} </style><style>body,td,a,p,.h{font-family:arial,sans-serif}body{margin:0;overflow-y:scroll}#gog{padding:3px 8px 0}td{line-height:.8em}.gac_m td{line-height:17px}form{margin-bottom:20px}.h{color:#1967d2}em{font-weight:bold;font-style:normal}.lst{height:25px;width:496px}.gsfi,.lst{font:18px arial,sans-serif}.gsfs{font:17px arial,sans-serif}.ds{display:inline-box;display:inline-block;margin:3px 0 4px;margin-left:4px}input{font-family:inherit}body{background:#fff;color:#000}a{color:#681da8;text-decoration:none}a:hover,a:active{text-decoration:underline}.fl a{color:#1967d2}a:visited{color:#681da8}.sblc{padding-top:5px}.sblc a{display:block;margin:2px 0;margin-left:13px;font-size:11px}.lsbb{background:#f8f9fa;border:solid 1px;border-color:#dadce0 #70757a #70757a #dadce0;height:30px}.lsbb{display:block}#WqQANb a{display:inline-block;margin:0 12px}.lsb{background:url(/images/nav_logo229.png) 0 -261px repeat-x;color:#000;border:none;cursor:pointer;height:30px;margin:0;outline:0;font:15px arial,sans-serif;vertical-align:top}.lsb:active{background:#dadce0}.lst:focus{outline:none}</style><script nonce="4KJzuMY6meDuiXxn_sgGfQ">(function(){{jsr:1,bv:1833,de:true}; var l=this||self;var m,n=null!=(m=l.mei)?m:1,p,q=null!=(p=l.sdo)?p:!0,r=0,t,u=google.erd,v=u.jsr;,b,d,h,e){e=void 0===e?2:e;b&&(t=a&&a.message);if(google.dl)return google.dl(a,e,d),null;if(0>v){window.console&&console.error(a,d);if(-2===v)throw a;b=!1}else b=!a||!a.message||"Error loading script"===a.message||r>=n&&!h?!1:!0;if(!b)return null;r++;d=d||{};b=encodeURIComponent;var c="/gen_204?atyp=i&ei="+b(google.kEI);google.kEXPI&&(c+="&jexpid="+b(google.kEXPI));c+="&srcpg="+b("&jsr="+b(u.jsr)+"&bver="+b(;var f=a.lineNumber;void 0!==f&&(c+="&line="+f);var g= a.fileName;g&&(0<g.indexOf("-extension:/")&&(e=3),c+="&script="+b(g),f&&g===window.location.href&&(f=document.documentElement.outerHTML.split("\n")[f],c+="&cad="+b(f?f.substring(0,300):"No script found.")));c+="&cad=ple_"+google.ple+".aple_"+google.aple;google.ple&&1===google.ple&&(e=2);c+="&jsel="+e;for(var k in d)c+="&",c+=b(k),c+="=",c+=b(d[k]);c=c+"&emsg="+b(": "+a.message);c=c+"&jsst="+b(a.stack||"N/A");12288<=c.length&&(c=c.substr(0,12288));a=c;h||google.log(0,"",a);return a};window.onerror=function(a,b,d,h,e){if(t!==a){a=e instanceof Error?e:Error(a);void 0===d||"lineNumber"in a||(a.lineNumber=d);void 0===b||"fileName"in a||(a.fileName=b);b=void 0;if(a.stack&&(-1!==a.stack.indexOf("?xjs=s0")||-1!==a.stack.indexOf("&xjs=s0"))){b=document.querySelectorAll("script[src*=\\/xjs\\/_\\/js\\/]");for(h=d=0;h<b.length;h++)d+=b[h].async?1:0;var c=e=h=-1,f=-1,g=-1;if(performance&&google.xjsu){h=0;e=google.timers.load.t.xjsee?1:0;f=c=0;g=performance.getEntriesByType("resource");for(var k= 0;k<g.length;k++)-1!==g[k].name.indexOf(google.xjsu)&&(h=1),-1!==g[k].name.indexOf("/xjs/_/js/")&&(c+=1,f+="script"===g[k].initiatorType?1:0);g=c-f}b={cad:"pl_"+h+".pe_"+e+".asc_"+d+".tsc_"+b.length+".fasc_"+(b.length-d)+".lxc_"+c+".lsx_"+f+".lnsx_"+g}},!1,b,!1,"SyntaxError"||"SyntaxError"===a.message.substring(0,11)||-1!==a.message.indexOf("Script error")?3:0)}t=null;q&&r>=n&&(window.onerror=null)};})();</script></head><body bgcolor="#fff"><script nonce="4KJzuMY6meDuiXxn_sgGfQ">(function(){var src='/images/nav_logo229.png';var iesg=false;document.body.onload = function(){window.n && window.n();if (document.images){new Image().src=src;} if (!iesg){document.f&&document.f.q.focus();document.gbqf&&document.gbqf.q.focus();} } })();</script><div id="mngb"><div id=gbar><nobr><b class=gb1>Search</b> <a class=gb1 href="">Images</a> <a class=gb1 href="">Maps</a> <a class=gb1 href="">Play</a> <a class=gb1 href="">YouTube</a> <a class=gb1 href="">News</a> <a class=gb1 href="">Gmail</a> <a class=gb1 href="">Drive</a> <a class=gb1 style="text-decoration:none" href=""><u>More</u> »</a></nobr></div><div id=guser width=100%><nobr><span id=gbn class=gbi></span><span id=gbf class=gbf></span><span id=gbe></span><a href="" class=gb4>Web History</a> | <a href="/preferences?hl=en" class=gb4>Settings</a> | <a target=_top id=gb_70 href="" class=gb4>Sign in</a></nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div></div><center><br clear="all" id="lgpd"><div id="lga"><img alt="Google" height="92" src="/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png" style="padding:28px 0 14px" width="272" id="hplogo"><br><br></div><form action="/search" name="f"><table cellpadding="0" cellspacing="0"><tr valign="top"><td width="25%"> </td><td align="center" nowrap=""><input name="ie" value="ISO-8859-1" type="hidden"><input value="en-GB" name="hl" type="hidden"><input name="source" type="hidden" value="hp"><input name="biw" type="hidden"><input name="bih" type="hidden"><div class="ds" style="height:32px;margin:4px 0"><input class="lst" style="margin:0;padding:5px 8px 0 6px;vertical-align:top;color:#000" autocomplete="off" value="" title="Google Search" maxlength="2048" name="q" size="57"></div><br style="line-height:0"><span class="ds"><span class="lsbb"><input class="lsb" value="Google Search" name="btnG" type="submit"></span></span><span class="ds"><span class="lsbb"><input class="lsb" id="tsuid_1" value="I'm Feeling Lucky" name="btnI" type="submit"><script nonce="4KJzuMY6meDuiXxn_sgGfQ">(function(){var id='tsuid_1';document.getElementById(id).onclick = function(){if (this.form.q.value){this.checked = 1;if (this.form.iflsig)this.form.iflsig.disabled = false;} else top.location='/doodles/';};})();</script><input value="AD69kcEAAAAAZL50o6s3v3S_wqQcB0TSZyINj-FLv2IJ" name="iflsig" type="hidden"></span></span></td><td class="fl sblc" align="left" nowrap="" width="25%"><a href="/advanced_search?hl=en-GB&authuser=0">Advanced search</a></td></tr></table><input id="gbv" name="gbv" type="hidden" value="1"><script nonce="4KJzuMY6meDuiXxn_sgGfQ">(function(){var a,b="1";if(document&&document.getElementById)if("undefined"!=typeof XMLHttpRequest)b="2";else if("undefined"!=typeof ActiveXObject){var c,d,e=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];for(c=0;d=e[c++];)try{new ActiveXObject(d),b="2"}catch(h){}}a=b;if("2"==a&&"&gbv=2")){var f=google.gbvu,g=document.getElementById("gbv");g&&(g.value=a);f&&window.setTimeout(function(){location.href=f},0)};}).call(this);</script></form><div id="gac_scont"></div><div style="font-size:83%;min-height:3.5em"><br></div><span id="footer"><div style="font-size:10pt"><div style="margin:19px auto;text-align:center" id="WqQANb"><a href="/intl/en/ads/">Advertising</a><a href="/services/">Business Solutions</a><a href="/intl/en/about.html">About Google</a><a href="" id="fehl"></a></div></div><p style="font-size:8pt;color:#70757a">© 2023 - <a href="/intl/en/policies/privacy/">Privacy</a> - <a href="/intl/en/policies/terms/">Terms</a></p></span></center><script nonce="4KJzuMY6meDuiXxn_sgGfQ">(function(){{height:757,width:1440};(function(){var a=window.innerWidth,b=window.innerHeight;if(!a||!b){var c=window.document,d="CSS1Compat"==c.compatMode?c.documentElement:c.body;a=d.clientWidth;b=d.clientHeight} if(a&&b&&(a!=google.cdo.width||b!=google.cdo.height)){var e=google,f=e.log,g="/client_204?&atyp=i&biw="+a+"&bih="+b+"&ei="+google.kEI,h="",k=[],l=void 0! 0!!;null!=l&&k.push(["opi",l.toString()]);for(var m=0;m<k.length;m++){if(0===m||0<m)h+="&";h+=k[m][0]+"="+k[m][1]},"","",g+h)};}).call(this);})();</script> <script nonce="4KJzuMY6meDuiXxn_sgGfQ">(function(){google.xjs={ck:'xjs.hp.s2H2D6UJ-8o.L.X.O',cs:'ACT90oGkFvlmkR5jsejFYQ2mTWk073_BrA',csss:'ACT90oH3M5Ryrdx46zrAqB3B95pFOUBtzw',excm:[],sepcss:false};})();</script> <script nonce="4KJzuMY6meDuiXxn_sgGfQ">(function(){var u='/xjs/_/js/k\x3dxjs.hp.en.kFtFMuRdpdA.O/am\x3dAAAAAAAAAAAAAAACAAAAAAAAAEAAQCcAQAEACw/d\x3d1/ed\x3d1/rs\x3dACT90oH2NEwiw6xVVVpsWVrz4w0TnNFnbQ/m\x3dsb_he,d,cEt90b,SNUn3,qddgKe,sTsDMc,dtl0hd,eHDfl';var amd=0; var d=this||self,e=function(b){return b};var f;var h=function(b){this.g=b};h.prototype.toString=function(){return this.g+""};var l={};var n=function(){var b=document;var a="SCRIPT";"application/xhtml+xml"===b.contentType&&(a=a.toLowerCase());return b.createElement(a)}; function p(){var b=u,a=function(){};google.lx=google.stvsc?a:function(){q(b);google.lx=a};google.bx||google.lx()} function r(b,a){a=null===a?"null":void 0===a?"undefined":a;if(void 0===f){var c=null;var k=d.trustedTypes;if(k&&k.createPolicy){try{c=k.createPolicy("goog#html",{createHTML:e,createScript:e,createScriptURL:e})}catch(t){d.console&&d.console.error(t.message)}f=c}else f=c}a=(c=f)?c.createScriptURL(a):a;a=new h(a,l);b.src=a instanceof h&&a.constructor===h?a.g:"type_error:TrustedResourceUrl";var g,m;(g=(a=null==(m=(g=(b.ownerDocument&&b.ownerDocument.defaultView||window).document).querySelector)?void,"script[nonce]"))?a.nonce||a.getAttribute("nonce")||"":"")&&b.setAttribute("nonce",g);}function q(b){google.timers&&google.timers.load&&google.tick&&google.tick("load","xjsls");var a=n();a.onerror=function(){google.ple=1};a.onload=function(){google.ple=0};r(a,b);google.aple=-1;google.psa=!0};google.xjsu=u;d._F_jsUrl=u;setTimeout(function(){0<amd?google.caft(function(){return p()},amd):p()},0);})();window._ = window._ || {};window._DumpException = _._DumpException = function(e){throw e;};window._s = window._s || {};_s._DumpException = _._DumpException;window._qs = window._qs || {};_qs._DumpException = _._DumpException;function _F_installCss(c){} (function(){google.jl={blt:'none',chnk:0,dw:false,dwu:true,emtn:0,end:0,ico:false,ikb:0,ine:false,injs:'none',injt:0,injth:0,injv2:false,lls:'default',pdt:0,rep:0,snet:true,strt:0,ubm:false,uwp:true};})();(function(){var pmc='{\x22d\x22:{},\x22sb_he\x22:{\x22agen\x22:true,\x22cgen\x22:true,\x22client\x22:\x22heirloom-hp\x22,\x22dh\x22:true,\x22ds\x22:\x22\x22,\x22fl\x22:true,\x22host\x22:\\x22,\x22jsonp\x22:true,\x22msgs\x22:{\x22cibl\x22:\x22Clear Search\x22,\x22dym\x22:\x22Did you mean:\x22,\x22lcky\x22:\x22I\\u0026#39;m Feeling Lucky\x22,\x22lml\x22:\x22Learn more\x22,\x22psrc\x22:\x22This search was removed from your \\u003Ca href\x3d\\\x22/history\\\x22\\u003EWeb History\\u003C/a\\u003E\x22,\x22psrl\x22:\x22Remove\x22,\x22sbit\x22:\x22Search by image\x22,\x22srch\x22:\x22Google Search\x22},\x22ovr\x22:{},\x22pq\x22:\x22\x22,\x22rfs\x22:[],\x22sbas\x22:\x220 3px 8px 0 rgba(0,0,0,0.2),0 0 0 1px rgba(0,0,0,0.08)\x22,\x22stok\x22:\x22V656lpC-zsS3QJhbOtFfjgF3TvE\x22}}';google.pmc=JSON.parse(pmc);})();(function(){ var b=function(a){var c=0;return function(){return c<a.length?{done:!1,value:a[c++]}:{done:!0}}},e=this||self;var g,h;a:{for(var k=["CLOSURE_FLAGS"],l=e,n=0;n<k.length;n++)if(l=l[k[n]],null==l){h=null;break a}h=l}var p=h&&h[610401301];g=null!=p?p:!1;var q,r=e.navigator;q=r?r.userAgentData||null:null;function t(a){return g?q?q.brands.some(function(c){return(c=c.brand)&&-1!=c.indexOf(a)}):!1:!1}function u(a){var c;a:{if(c=e.navigator)if(c=c.userAgent)break a;c=""}return-1!=c.indexOf(a)};function v(){return g?!!q&&0<q.brands.length:!1}function w(){return u("Safari")&&!(x()||(v()?0:u("Coast"))||(v()?0:u("Opera"))||(v()?0:u("Edge"))||(v()?t("Microsoft Edge"):u("Edg/"))||(v()?t("Opera"):u("OPR"))||u("Firefox")||u("FxiOS")||u("Silk")||u("Android"))}function x(){return v()?t("Chromium"):(u("Chrome")||u("CriOS"))&&!(v()?0:u("Edge"))||u("Silk")}function y(){return u("Android")&&!(x()||u("Firefox")||u("FxiOS")||(v()?0:u("Opera"))||u("Silk"))};var z=v()?!1:u("Trident")||u("MSIE");y();x();w();var A=!z&&!w(),D=function(a){if(/-[a-z]/.test("ved"))return null;if(A&&a.dataset){if(y()&&!("ved"in a.dataset))return null;a=a.dataset.ved;return void 0===a?null:a}return a.getAttribute("data-"+"ved".replace(/([A-Z])/g,"-$1").toLowerCase())};var E=[],F=null;function G(a){;var,f=[],H=f.concat,d=E;if(!(d instanceof Array)){var m="undefined"!=typeof Symbol&&Symbol.iterator&&d[Symbol.iterator];if(m);else if("number"==typeof d.length)d={next:b(d)};else throw Error("a`"+String(d));for(var B=[];!(;)B.push(m.value);d=B},d,[c]);if(a&&a instanceof HTMLElement)if(a===F){if(c=4<=E.length)c=5>(E[E.length-1]-E[E.length-4])/1E3;if(c){c=google.getEI(a);a.hasAttribute("data-ved")?f=a?D(a)||"":"":f=(f= a.closest("[data-ved]"))?D(f)||"":"";f=f||"";if(a.hasAttribute("jsname"))a=a.getAttribute("jsname");else{var C;a=null==(C=a.closest("[jsname]"))?void 0:C.getAttribute("jsname")}google.log("rcm","&ei="+c+"&ved="+f+"&jsname="+(a||""))}}else F=a,E=[c]}window.document.addEventListener("DOMContentLoaded",function(){document.body.addEventListener("click",G)});}).call(this);</script></body></html>

A little HTML and a LOT of JavaScript. You can test this by using curl or postman.

So, a web page is a structured document consisting of HTML, styled with CSS and functionality added by JavaScript. That’s an incredibly simplified description, of course, JavaScript can also handle structure and styling, and HTML can partially handle styling too. The purpose of the content of a web page is to tell your web browser how to present the content to you.

A website consists of one or more web pages.


Before and After the Server

When a web page is requested and sent to your browser, it’ll usually return a structured HTML document that your browser can render for you. The exception to this is something like a React or Angular app where the content is driven by JavaScript and in those instances, the JavaScript is sent to your browser, which is then executed and that JavaScript execution builds the document that you see.

In a typical instance, however, lets take PHP for example, your browser sends a request to the server for a particular page, lets say index.php, and the web server will process that index.php file via the PHP interpreter and then return the content. So the web server will return a HTML document but it will consist of dynamically generated content that is produced by PHP.

The File Extension

The file extension is important here. When you request a HTML file from a web server, it knows to just return the contents of that file. When you request a PHP file from the web server, it knows to first run that file through the PHP interpreter and then return the PHP-generated content. This is, of course, assuming the web server supports PHP and is configured properly.

A Common Problem ⚠️

A common problem that we see a lot of in our programming community, and I mentioned at the start of this post, is that new, aspiring web developers overlook the file extension. A web server does not know if there is PHP inside of a file unless you tell it, and you tell it by using the .php file extension. You cannot put PHP code in a HTML file and expect it to execute, it just won’t work.

The Web Server

A web server is simply an application that runs on a computer, somewhere. This computer can be the one you are on right now, a spare one in the next room, one provided by a hosting company, anywhere in the world. The job of the web server is to process web requests and return the appropriate content. Typically, it will listen out for connections on ports 80 and 443, for HTTP and HTTPS requests, respectively. a HTTPS request is a HTTP request wrapped in a secure protocol called Transport Layer Security, or TLS. Nine out of ten times, you don’t need to worry about TLS when developing locally. Your production server should have an SSL certificate installed on it which it will then provide with each response, and doing this locally with a self-signed certificate is just a nuisance, and usually unnecessary.

A web server has a document root or root directory which contains all the files and directories that it will serve to the internet. Anything outside of this document root is not ordinarily accessible via the web server, the main exception being a misconfigured server.

Let’s say we’re on linux with an apache web server, we can probably find our root directory at /var/www/html, or if we installed XAMPP on Windows, it’ll be located in C:\xampp\htdocs, assuming you installed XAMPP at C:\xampp. public_html is another common root directory name. Anything in the root directory on a publicly accessible web server is publicly accessible.

You NEED a web server

You absolutely need a web server for web development if you plan on using any back-end technology such as PHP. We’ll talk about front vs back end a little later. Even if you only plan on using simple HTML/JS/CSS, it’s still better to have a local web server to use than to just load the files in the browser.

Files in the browser?

Remember my pre-rant about URLs starting with file://? This is another common issue we see in our programming community and it’s why I have been rambling about web servers so much. Opening a file directly in your browser works if its just HTML/CSS/JS, your browser will still make it look pretty. But it isn’t being served to you via a web server in that way, it’s simply reading a file from disk and showing you the rendered result. If your URL starts with file://, you’re doing it wrong. Try opening a PHP file like that! 👀

What is publicly accessible?

Well, it means what it says. Accessible, publicly. Available to anyone. Which leads us to another common issue.

Quite often, we hear of someone that will set up a local web server at home and cannot access it outside of their home. This is due to a lack of port forwarding. When you visit your public IP address, the request will usually reach your home router and this router doesn’t know what to do with that request unless you tell it what to do. So, if you want to access your locally hosted website outside of your home network, you need to do a couple of things:

Firstly, you probably want to configure your router to assign the same local IP to your server computer, a static IP. That way, the router will always know who that computer is on the network. For example, lets say that my local server is hosted on, every time I restart that computer, it will always be given the local IP, because I set my router to always assign that IP to that machine. It does this by using the machine’s MAC address as an identifier.

Secondly, you will want to configure your router to forward incoming requests on port 80 and/or port 443 to be redirected to the local IP of your server computer.

⚠️ This isn’t recommended. Having a local computer on the public internet like this is a pretty big security risk. You have the downsides of having to monitor your server Operating System and all the relevant software for new bugs and exploits, patch them ASAP, you have no DDoS protection, if somebody does breach your server security then all the other devices on your local network are exposed, it’s probably in breach of your ISP terms. Not to mention that unless you’re a cyber security expert, it’d be very difficult to detect any breaches anyway. It’s just a big headache, and that’s why most web developers don’t do this.

That said, if you work on multiple computers like I do from time to time, or even just want to run a local web application of some kind, you can absolutely follow the first step above and just use the server within your local network.

Local, Local Network, Public, Wide-Area-Network

All the networks!

What’s the difference?

Typically, a local server means a server that is running on the computer you are on, it is local to that computer.

A local network server means that a server is running on your local network, and any device within that network can access it. It may also be referred to as a LAN server or just “my server”.

A public server means that anybody on the internet can access that server.

wide area network – I just threw this in for the sake of it, you may have heard the term(s) WAN and LAN before. LAN is local, WAN is wide, as in wide-open, public, the internet.

The Web Development Setup

A typical setup for web development will usually involve a local server where you do your work and then a production server where you deploy your work. Perhaps a staging server too which is like an identical setup to the production server but without being public. This allows you to test a website in a live environment before actually publishing it to your users.

Of course there may be some version control and CI/CD involved too but that’s beyond the scope of this discussion.

Setting Up a Local Server

The majority of people I have come across just getting in to web development are working on Windows OS, so I’ll talk about that here, since linux and mac have near infinite variations of how to set up a web server, it’d be best to figure out the appropriate steps yourself, if you fit that category. I develop on a mac, homebrew is your friend.

I’m most familiar with XAMPP from apachefriends, which is a bundle of software you can install on Windows that includes Apache, MySQL, PHP and Perl. This lets you hit the ground running with web development because it installs all you need to get started with those things. I know nothing of Perl, though!

Once you install XAMPP, make your way to the installation directory and run the XAMPP control panel and you’ll see something similar to this:

XAMPP control panel

I apologise that it’s a bit blurry, I didn’t take that screenshot, I’ll probably replace it in the near future.

Click “Start” on the row that “apache” is on, and your web server should be up and running. Visit http://localhost/ to see it. Also just as a reminder, the root directory for this web server is located in the htdocs directory within the XAMPP install directory. Create a file in here called phpinfo.php and put this code inside:

<?php phpinfo();

and you’ll see your web server PHP information at http://localhost/phpinfo.php – A quick and easy way to check if PHP is working properly after installation.

You can also configure XAMPP to start as a service so it runs when you fire up your PC, if you desire.

If you’re not on Windows, you’ll want to install apache, php and mysql (probably MariaDB nowadays) and configure it appropriately. You don’t strictly need mysql, its a relational database system which is commonly used alongside PHP to store, well, data. It is not exclusively for PHP or even web development, however.


You might’ve noticed that I have said localhost a few times; this is simply a loopback address found in your system hosts file which points to and is generally the “web address” you visit to access your local web server.

Feed Me More

HTTP Request Methods

There are a few important HTTP request methods worth mentioning. You may have heard the term CRUD before, which refers to CREATE/READ/UPDATE/DELETE. Each of these actions has an appropriate request method:- POST/GET/PUT/DELETE. In practice, GET and POST are probably the most common. When you visit a web address, you’re making a GET request. When you submit a form, it’s probably a POST request, although it might be a PUT or even PATCH request, if it’s to update some data as opposed to creating new data.

The other request methods are more common when using REST APIs as opposed to just using your web browser. There’s also the OPTIONS request, HEAD, CONNECT and TRACE. You can read about them here.

Finding A Web Server From A Web Address

This is purely supplemental information for the curious. When you type a website URL into your browser to visit that site, your browser sends a request to your designated DNS server. The DNS server IP might be defined on your system or on your router, or provided by your ISP. The DNS server is a domain name server and translates a friendly website name such as into an IP address for your browser to use, such as Of course it’s a little more complicated than that, but that’s the simplification.

Typical File Types

There are primarily 3 or 4 file types when discussing traditional web development. Those are:

  • HTML files – Files containing HTML code
  • PHP files – Files containing PHP and/or HTML code
  • JavaScript files – Files containing JavaScript
  • CSS files – Files containing stylesheet data

In the real world, you’ll often find that .js and .css files are included within a web page as separate files. We have the <script> and <link> HTML tags for that. This lets use have better readability and maintainability to our projects. That said, both JS and CSS can be written in-line within a HTML document.

PHP files, although containing php code, often contain HTML too. Sometimes this is frowned upon due to mixing logic with structure, and other times its not avoidable.

HTML files are the most basic of the bunch, they just consist of HTML. Now, that HTML can include JS and CSS either in-line or via external files, but it can’t include PHP.

index dot what?

If you have a web server with nothing on it and visit the root directory via the URL, you’ll likely see an empty directory and/or an apache information page. Now, if you put an index.html file in there and visit the same URL without including “index.html”, it will still load index.html. Why? It’s part of the default configuration, at least for the apache web server. So if I had a directory called ‘seven’ on my local server and visited http://localhost/seven/, I would see this:

You may also see some server version information displayed such as “apache server 2.2” or something.

If I created an index.html file in that directory and visited the same URL again, I would only see a blank page (assuming index.html is empty), because the web server will serve index.html by default.

The same applies to files called index.php, so you can automatically serve index.php without the URL explicitly requesting it. On my local server, the HTML file takes precedence if both index.html and index.php exist, but this and even whether or not it should automatically serve these files, is entirely configurable within the web server configuration file. But apache configuration is a whole different can of worms that we wont be touching on today!

Front End vs Back End

You’ll often hear of front-end, back-end and full-stack developers. The terms are relatively simple for the most-part. A front-end developer will spend the majority, if not all, of their time working on parts of the website that the user will see and interact with. A back-end developer is the opposite, working on stuff that is on the server-side. A PHP or nodeJS developer would be primarily a back-end developer.

A full-stack developer, on the other hand, will do all of this work. Writing the code that produces the UI that end users will see and interact with, and also the server-side code that provides data management for the front-end. It’s more and more common for companies to seek a full-stack developer in this day and age because it’s essentially twice the workload for the cost of a single person, and the majority of web developers do indeed learn how to develop within a full-stack environment, it’s simply the nature of web development. When you’re learning, you don’t usually have a counter-part to work the back-end while you learn front-end or vice versa, so you learn it all.

THE Summary

So, you want the TL;DR, huh? Right.

  • A website is a collection of one or more web pages
  • A web page is a structured document consisting of HTML, JavaScript and CSS (usually)
  • A web server will deliver specific content based on a request; such as requesting page.html will return the content of page.html
  • A web server doesn’t know a file contains PHP, if it isn’t a PHP file
  • You should run a local web server for web development
  • Visit your local web server to access files, do not open files directly (don’t have a URL starting with file://)
  • Don’t put PHP in .html files!
  • Don’t expose a local web server to the world
  • Some IDEs include their own version of PHP. Mine does this; I usually create a new project within my web server root directory and that way I can directly access the content as I create/edit it. Otherwise, you can find yourself in a scenario where your local web server has the PHP mysqli module enabled, but your IDE does not. Work smarter, not harder, don’t work with multiple versions of PHP while developing.

Side Note

Through sheer laziness, I just wrote this html/js code to auto-generate URLs for the table of contents for this post 😂
<div id="container"> <h1 id="the-pre-rant">The Pre-rant</h1> <h1 id="what-is-a-website">What IS a website?</h1> <h2 id="the-web-page">The web page</h2> <h2 id="before-and-after-the-server">Before and After the Server</h2> <h4 id="file-extensions-matter">The File Extension</h4> <h4 id="a-common-problem-extensions">A Common Problem ⚠️</h4> <h1 id="the-web-server">The Web Server</h1> <h3 id="you-need-a-server">You NEED a web server</h3> <h3 id="files-vs-server">Files in the browser?</h3> <h2 id="setting-up-local-server">Setting Up a Local Server</h2> <h2 id="localhost">Localhost</h2> <h2 id="http-request-methods">HTTP Request Methods</h2> <h2 id="typical-file-types">Typical File types</h2> <h2 id="index-dot-what">index dot what?</h2> <h1 id="the-summary">THE Summary</h1> </div> <div id="out"></div> <script> function fix(n) { let x = n.split('-'); let y = []; x.forEach(z=>{ y.push(z[0].toUpperCase() + z.slice(1)); }); return y.join(' '); } var out = document.getElementById('out'); let tmp = ""; var nodes = document.querySelector('#container').children; for(var i=0; i<nodes.length; i++) { tmp += '<a href="#' + nodes[i].id + '">' + fix(nodes[i].id) + '</a>\n'; } out.innerText = tmp; </script>

comments bru.

11 thoughts on “The ABSOLUTE basics of Web Development

  1. Pingback: zoloft and xanax
  2. Pingback: gabapentin dea

Comments are closed.