WARNING: VERY LONG POST. GRAB A DRINK BEFORE GETTING COMFORTABLE, OR CLICK THE BACK BUTTON OUT OF FEAR.
Starting Monday I will be an a two week vacation. Other than a handful of days I don't really plan on doing much (more of a "staycation"). In that time though I'd like to resurrect a very old project and make my third attempt at creating a game (tried twice in the past). It's more or less text based, but will live in the browser and have buttons, checkboxes, etc. My skill level and skillset is much different in the past when I made my first two attempts (third time is a charm, right?). I am also a lot more prepared as I have mapped out the pages, menu structure, and did some basic sketches of wireframes before beginning (and figured out the colour scheme). I also have the project broken out into 9 phases or milestones (originally I had 3).
Anyway, below are some questions as I'd like to do this "right" and to maximize my motivation and thus the likelihood the project will actually be completed (I'm well aware it will not be completed in the two weeks - I am just using that time to get started :p).
1a. Early branching in Git
What is sort of the accepted workflow or best practice approach in the infancy of a project regarding branches and commits? In the few projects I have worked on with Git I created the repository and the .gitignore file and that was my first commit (the message is always "Initial commit."). I really like the master/development/feature workflow as outlined here. But at what point should branches like development be created? In other words, how far into your project should you go before you stop working directly on your master branch? I have always been under the impression that you should rarely or never work on the master branch and to always consider it production code. This leads into the second question:
1b. "Commit early, commit often"
I have also heard that mantra, too. That's sounds like a solid plan, but is there such a thing as going over board? I haven't really worked out how often to be making commits. I just sort of do them when I complete a reasonable "task" or logical piece of code. Is that too often? Is it considered best practice to commit larger, but more logical chunks or to commit smaller chunks and use tagging/versioning to "group" larger, logical chunks? Here is a commit log for a "for-fun" little project I made for an old video game. Is that too often, not enough, or somewhere in between (also are my comments acceptable in their brevity and description?). I find myself making a commit maybe every 5 to 10 minutes. Refactor a couple JavaScript functions, commit. Updated HTML markup, commit. Change some CSS properties, commit. Good or bad behaviour?
1c. Versioning
I assume those who use Git use some sort of scheme to version their software. I'm personally partial to the MAJOR.MINOR.PATCH scheme. I also have some sort of obsession with versions; I'm constantly checking for updates for every facet of software I have from Windows to my browser to WordPress to FileZilla. Anyway, do you usually start projects as v0.1.0? To me that's the logical starting point, but I'd love to hear others' perspective.
1d. Committing: Fast forward or no?
I've looked this up but to be honest it escapes me. I don't really deal with it directly anymore though since I just commit via PhpStorm now and let it do whatever it is that it does. But is there a "best practices" approach to this? According to that Git branching model link above it's better to NOT fast forward (--no-ff). Any way to find out what PhpStorm does by default (and if there is anyway to change it)?
1e. Committing: Should I track compiled files or no?
I seem to remember that this was considered poor practice. In the past I had run into issues with my .less files auto-compiling to .css when I switched branches because the background software I was using was detecting changes. This isn't really an issue for me anymore however since I use PhpStorm and file watchers (I have NPM installed with Less and UglifyJS). They aren't triggered when I switch between branches. But regardless, is it considered good or poor practice to track these files (or does it even matter)?
1f. Merging: Should Branches be Deleted?
Aside from the master and development branches, should feature branches and others (hotfixes, etc.) be deleted once merged? I assume so but just wanted to hear others' opinions.
1g. Dealing With Merge Conflicts - Recommended Software
PhpStorm allows you to set an external merge/diff tool for when you have conflicts. Does anyone have any recommendations? I looked online but found a lot of mixed opinions. I'm on Windows 7 x64. I guess ideally I'd want 3 panes: The code in the current branch, the code in the branch that I am merging from, and the "would be" result of my merging. Apparently some have four panes, but I think I can deal with only three.
2a. Exception Handling
I totally know what exception handling is and I have used it way, way back in college when I was doing .NET and Java. I am a little embarrassed to say that I have pretty much never used it in PHP. I figured I should get in the habit as it's a very useful tool in any developer's toolbox. I guess it always just seemed like PHP was able to handle any issue with an if/else block. Anyway, I am a little unclear on a thing or two. Namely I'm not sure exactly how aggressive I should be when using a try/catch block. I am going to attempt to make my code very modular (more on this later) so what happens if you have a function with a try/catch block that calls another function with a try/catch block and the second one throws the exception? My understanding is it "bubbles" up to the initial caller.
Furthermore my understanding of exceptions is a little hazey with respect to how it terminates or doesn't terminate program flow. I have always been under the impression that an uncaught exception kills the script immediately not unlike a call to die() or even an exit statement. But my understanding of exceptions in PHP is that if you catch the exception the program doesn't exit and instead does whatever you tell it to in the catch block. Is my understanding at least a little correct? I guess I just have to work out what to do in those catch blocks.
I have been doing research in this area online and checking out some videos on YouTube on how to move from a plate of if/else spaghetti code to utilizing exception handling. I don't have a solid grasp on it quite yet, but I think I'll get there. Like everything though, experience will be the best teacher and I'll just have to dive in.
2b. Is it worth it to create an error class?
I admittedly got this idea from WordPress. They have a WP_Error class that is returned from certain functions if they fail. It allows multiple error messages and error codes. They also have a function to check if the return of said functions is a WP_Error object. Good or bad idea? Should this even be considered, or can this sort of thing be easily handled via intelligent exception handling?
3. Should all functions be part of a class?
I am trying to go for more of a on OOP approach than I have in past projects. I want my functions to be very precise, concise, and be reusable/modular. I know there will logical grouping of functions (user functions, authentication functions, etc.) which can easily be organized into classes, but there will probably also be miscellaneous functions that don't really fit anywhere. I assume that it's totally okay to have some random functions maybe in a helper.php or misc.php file? Or would it be just as "correct" to have a Helper or Miscellaneous class and put them in there? I want to take advantage of the spl_autoload_register function as much as possible and minimize my "includes" as much as possible, too.
3a. Static vs. Non-Static
Does it really matter? I personally prefer the -> syntax to the :: syntax but PhpStorm helps out so in the end it doesn't really matter. Any technical reason to choose one over the other, aside from that extra line of having to instantiate an object with a non-static approach?
4. Should I create a DAL?
Is it really necessary to do this? To be honest I'd like to omit as much (or all) queries from my classes as I can, but maybe I am not wrapping my head around this as much as I thought I did. Would the DAL have generic functions like insert(), update(), etc. or would they be more specific like insert_user(), update_user(), etc.? If the latter than wouldn't I more or less duplicating code? In the sense that there will probably be a insert_user() or create_user() function in the User class, which would do some stuff and then eventually call the insert_user() function in the DAL.
Perhaps I am confusing the purpose of the DAL. Its purpose is to make sure my application is not married to a specific database, and nothing else. Its purpose should not be to facilitate operations in my application. Or can its purpose be both, or should there be another layer in there somewhere that does facilitate operations in my application (what I mean is for example the User class doesn't write any queries itself and instead passes the action off to another class).
I think that's all my questions. Whew. If I think of anything else I'll be sure to post. If you have read this whole post and made it this far than thank you (and give yourself a pat on the back)!
I'll update this thread with progress and probably questions. Also until at least v1.0.0 I'll make the repository public; I'd love to hear feedback on code or just any advice in general.
Thank you so much for reading!