This article is not a self-impressed article about parochialism. I am reflecting on technology, originality, and the endless tribal boundaries.
My first large scale language was Java (i.e. projects that take months and when just code is more than a few hundred kilobytes). As long as you limit to Java inside the JVM, this has good code management primitives. This is a side-effect of being a static-type OO compiled language. Java has namespaces, so its easier to manage and isolate. Whilst I had less experience, this is my benchmark for all later design and architecture.
My first real job was to provide business systems inside PHP4.1, then quite quickly PHP4.2. PHP is an ugly language. Manual include() statements, the common mistake of including your page headers, and by side effect open a database connection; I think is brain damaged. I did then. At this point, I was a less accurate typist; and code reuse definitely saw a reduction in timescales, due to not needing to fix typos. My earliest solution was to have a flat script that parsed arguments, had all the includes, and generally fork()-ed and bootstrapped. If the script passed this point, you had a reasonable certainty that all necessary assets/ resources where available, so the service as viable. I didn't write any websites for a long time.
More recent PHP code may use classloaders (and exceptions, access modifiers, closures, namespaces etc). My more recent employers mention IP less often, and don't mind me using frameworks/ libraries. My above text is boring tech history. Class loading may be done lazily / dynamically ~ which is better for short-lived varied-execution-path activities; or statically in advance ~ massively better for anything to do with strict timing on execution, and very long lived processes. For example, my above business systems ~ when I had a good grip on the technology ~ had a process lifespan to match the requirements iteration. Classes may be mapped on service start up (which Java system classes do), or discovered by a rigid naming method (see ZF1 paragraph long class names). There are also hybrid solutions, that avoid the excessive naming schemes, and the cost of building the maps. I think the SF2 classloader and mapper is better than the old ZF2 one. The SF2 mapper uses a combination of coder-specified object-creation definitions (called services.yml), and directory enumeration. This combined list is written out to a classes.map and a custom class loader instantiates against this list. The Yii framework 1 uses a lazy loading, compound naming ~ which looks like a namespace; with optional mapping hints. I think this is a function of being started before PHP5.3 was built. Ancestor code 2 ~ still used by some businesses ~ has been built without namespaces. This is a link to an older version of ZF1 on purpose to avoid notes on autoloaders, that are available from PHP5.2 and above. ZF1 started along time ago, for PHP4; and uses a complex class naming scheme as a consequence. The classnames encode what directories the PHP file is in, but the PHP named after the last section of the class. A popular framework for e-commerce is Magento, which is ZF1 with extra bits, including a management GUI. ZF1 where continuing to work against the older and less engineered code, so publish things 3. ZF2 compiles all classes on process start 4, and is designed to work with php-cgi 5. ZF2 does ship with several autoloaders. Other more-recent frameworks, Laravel 6 and Sylius 7 use SF2 components for classloading. I have used CodeIgniter 8 for one project; the framework wants wide compatibility with old versions of PHP, and uses a custom loader 9 ~ not SPL. The popularity of current PHP frameworks is reported 10 11.
The recommended method for code loading is to use spl_autoload suite 12. This was added in 5.2, but became more useful in 5.3. This is just a programmer controllable point to compile classes, similar to Perl. When you write this class, it is recommended to do the directory mapping yourself, as it is faster that PHP repeatedly walking all the directories.
Back to PHP4: After a year (or so), I got enough control on my process to pitch more aggressively. I want to avoid statically defining dependant classes. This reduces reuse and makes testing harder. I was still stuck to PHP4, so had no Interfaces. I created a Manager class, have it create all the classes, hold the references, and hand these out. Without Interfaces, IoC is too messy, but you can effect DI. The Manager supplied objects, by name, not type. A config defined the late-linking, and all the object names. Every class has a standardised constructor, which takes a reference to the Manager, and the Config. I write reference repeatedly, as I needed to manage the amount of RAM consumed (accidental copy of datacaches will lead to process death). The Manager took about a day to test and write, and was used in all later points.
My first actual PHP5 project was a fast CMS. I wanted to have public PHP5 code, and didn't think that just using an existing tool would count for anything. By the time I had iterated down to less urgent features like class loaders, my host had updated to PHP5.2. I built a static loader/linker, but dynamic config for this. My class set was quite small so static just made it simpler. This needed to interoperate with the class loading technology of my included libraries.
I write to defend the assertion that I am not climbing out of flat scripts making HTML table layouts, to procedural code, now grudgingly using objects. I don't use Wordpress, or write about it, complete with hundreds of screengrabs. There is nothing actually bad with Wordpress, but the culture surrounding it severely dumbs-down engineering. The main Wordpress invites people to use a tarball. This is my profession, I have spent thousands on study, and thousands of hours reading background material. A different site by a different person would write about how to install things again.