How I used PHP's magic methods and why
When PHP5 was released there were a couple new additions, magic methods. The best way to think about a magic method is a function you didn't have to write or include that helps keep your code running smoothly.
A couple of the many magic methods
__set() and __get() were used to create some neat functionality for this site.
__set()
Normally when setting variables for use on a page you need to declare each and every one of them. When doing so this invokes the __set() magic method. What happens if you try and set a variable that you don't know the name of or if it may not always exist? To use a real example, I was setting properties in my Template class that were ever changing.
When I try and set a property that does not exist, such as $this->page_id = 6;, the Template class invokes the __set($index, $value) method which results in $this->vars[page_id] = 6 being set.
__get()
The converse of the __set() method is __get(), which is invoked when you try and retrieve a variable or property that is either not set or not accessible.
Because in my above example $this->vars is private, it is inaccessible from other classes. If I wanted to change this functionality I would need to essentially change how the __get() method works, or overload it.
If I had this code in my Template class I would then be able to reference the vars property from another class. The ampersand before __get() means to use references when working with the variables. When you pass by reference it is best to forget about the value of the variable and think more about what the variable holds. Changing the value of a variable when you pass it by reference changes the value of the variable outside of the function/method as well. It is often used to 'return' multiple values without actually using the return keywords. I touched on passing by reference in a past post.
What I learned from creating my own CMS
First of all you should know my reasoning behind building this from scratch. I wasn't trying to reinvent the wheel, I was merely trying to figure out how the wheel works so I that I could make the car run more smoothly.
The Structure
Having worked with Drupal, Wordpress, and various other CMSs I knew the importance of good file structure. After looking at various sites I decided on a common structure to start with.
Each time a user clicks a link it goes through a process to find and display the correct page.
- The system includes all of the application classes, this includes the controller, registry, router, and template)
- The DB is then instantiated using the Singleton design pattern
- The next step is to instantiate the registry object. This stores information about the URL, page id, user id, user permissions, etc... it is basically the equivalent of a config file. Site wide variables are stored here so they can be passed to the controller files
- The router object is next to be instantiated. The router takes the URI and breaks it into parts. From these parts it knows to call a certain controller and action. For instance www.levijackson.net/page/checkpage/1 would call the page controller, the action (or method) checkpage, and it would pass in the id of 1 to the action to process.
- The next step is to instantiate the template object. The registry object we called earlier holds all of the template variables to use in building the dynamic pages.
- The last thing that occurs (or the first from the user perspective) is that the index controller is called which takes ALL of the info we generate in the above steps and puts it all together into one neat and tidy page.
Snippet
Upsides to working in OOP PHP
After working with Object Oriented PHP on a large project for the first time I found that I enjoyed it much more than I thought. Some of the things I enjoyed while working on the OOP CMS were:
- How easy it was to debug when most processes pass through one file.
- How easy it was to write an action and deploy it site wide.
- How easy it is to change the design without changing the architecture of the site.
- How easy it was to keep with the DRY (Don't Repeat Yourself) principle of coding.
Conclusion
It took entirely too long to bring this CMS from development to production. Total time would put this project at around 60 hours of research, coding, design, and using a punching bag to alleviate stress. From doing this it has definitely opened my eyes to how important it is to be DRY when coding.
Access nested attributes using SimpleXML
I have been working on writing a function to edit an XML document using just SimpleXML. This is a sample of the XML file I am working with today:
Accessing the children of Employees was the easy part. Create the SimpleXML object and the nodes become properties of the object.
The trouble I had was in accessing the attributes of the child nodes. I was thinking about it in terms of the attributes being arrays, when in fact they were a child simpleXML object! After some reading about the SimpleXML object I came this solution for accessing the user type for my "employee".
What this does is select the child node of Employee called "Access_Info". From there the attributes() method is called which returns a new simpleXML object to work with. So what was once hard is now as easy as the first example. Once we have the SimpleXML object we can then access the values quite easily.
Conclusion
So what did I take away from this experience? Well for starters just because it looks complicated, doesn't make it so. The biggest issue I had was that I was being returned SimpleXML objects and I wasn't sure how to access the information. It became easier to work with once I could visually see that objects can nests inside one another. Just because the SimpleXML object was a child of another object didn't mean I couldn't use the same methods on either. Essentially what I learned was that when given a situation that I am unsure of, the best way to work through it is to assess my options.
Passing by reference in PHP
I was just reading up on some PHP while I work on one of my final projects and I came across the topic of passing by reference. Which if you are not familiar with it, this is the PHP.net reference page. I had no idea that it existed and it instantly reminded me of the past three weeks of C++ where we have been discussing and using pointers as a means of "returning" more than one value from a function.
A good explanation of a reference is:
"References are a way to have multiple variables referencing the same variable container using different names -- so whatever name you're using an operation on that variable will always have an effect on the others." - Johannes Schlüter
My experience with pointers and passing by reference has been in the classroom and so the only benefit I have seen is that you can modify variables outside of a function. Check this snippet out for instance:
Conclusion
I don't know that I would really pass by reference outside of the classroom at this stage as I have not encountered a situation where I needed to return or modify more than one value at a time.
Google Ranking
Last week I was watching state of the index by Matt Cutts and he mentioned in the future Google may rank sites based on how quickly the page loads. So I decided to test my site.
The test
I ran my site through Web Page Test and got some astonishing results. I failed on almost every account! Not having a lot of time there were some suggestions I was able to take an implement easily. The first was to enable gzip. I had always though I would have to install some fancy script to do this so I found excuses not to do it. Now I know that is not the case. It can be enabled quite easily if you have access to your php.ini file or if you just want to include this nice little snippet at the top of your page! I was also told that I had too many css and js files included and it suggested combining them. Understandable, but how can one combine the core jQuery file and their main script file and have it still be maintainable? I compromised and combined my js script files that I wrote together.
The change
I am not sure if it is because of the simple changes I made or if it is because I have been writing a little more frequently, but my ranking has improved when searching on my name. I usually do a search for 'Levi Jackson' to see where I pop up and currently I am number 3 when I had been 7 or lower for the longest time. Regardless it has made me more interested in optimizing my web pages than I have ever been before.
The current stats
I still fail many of the tests! What I do plan on working on next is to figure out a method of combining all of my js files or perhaps getting rid of some of them. At the same time I am going to work on a method of caching content so as to not require a call to the db unless there has been a change to a file since the last visit.
Conclusion
If page speed isn't factored into the ranking yet... it will be. It is better to fix it now when it doesn't play a role than to find your site dropping in ranking and need to rig something together to fix it then.
Social Media