What should be an instance of a class in php? - php

In PHP 5.2.x, mySQL 5.x
Im having a bit of an issue wrapping my head around what should and should not be an instance of a class in php because they are not persistent once the page is rendered.
Say I have a list of comments. To me, it would make sense that every comment be its own object because I can call actions on them, and they hold properties. If I was doing this in another language (one that has persistent state and can be interacted with), I would do it that way.
But it seems wasteful because to do that I have a loop that is calling new() and it would probably mean that I need to access the database for each instance (also bad).
But maybe im missing something.
Php just seems different in how I think about class and objects. When should something be a class instance, and when not?

This is a subjective issue, so I'll try to gather my thoughts coherently:
Persistence in PHP has sort of a different meaning. Your thinking that each comment should be an object because comments have actions which can be performed on them seems correct. The fact that the objects won't persist across a page load isn't really relevant. It isn't uncommon in PHP to use an object in one script, which gets destroyed when the script completes, and then re-instantiate it on a subsequent page load.
Object-oriented programming provides (among other things) code organization and code reuse. Even if an object is only really used once during the execution of a script, if defining its class aids in program organization, you are right to do so.
You usually needn't worry about resource wastefulness until it starts to become a problem; if your server is constantly taxed to where it degrades your user experience or limits your expansion, then it is time to optimize.
Addendum:
Another reason defining a class for your comments is that doing so could pay dividends later when you need to extend the class. Suppose you decide to implement something like a comment reply. The reply is itself just a comment, but holds some extra attributes about the comment to which it refers. You can extend the Comment object to add those attributes and additional functionality.

Related

Pinning objects to memory

I'm trying to think of a simple way to permanently pin a PHP object to memory and then have it available to other more transient objects to message with during their normal job of servicing page requests. I'm still relatively new to Wordpress so maybe I'm making things too complicated ... let me demonstrate through an example what I would want to be able to do:
Have a UOM (unit of measure) object load up at startup that polls the database for a list of units, the default units, categories of units (e.g., pounds is an imperial measurement), conversion rates, etc.
Subsequent service requests that want to use UOM conversions or lookups would simply call the global UOM object ( $UOM->get_measures_for_category ('speed') ). This object would already be in memory and not need to go back to the database to service requests.
An update() method on UOM would allow event or timing based triggers to ask for the UOM object to update itself.
This is just one example of where there is a some relatively static set of data that is used regularly by service requests and the repeated querying of the database would be wasteful. Hopefully people are familiar with this pattern and could maybe point me to some examples of how you would do this in a Wordpress/PHP environment.
For what you want this is not the best way of doing it. However what you're talking about requires knowledge of one of the fundamental tennets of PHP and programming in general aka scope, namely what the global scope is.
So, if you declare this in the global scope:
$uom = new UOM_Class();
Then in any file afterwards you write:
global $uom;
$uom->something();
it will work.
This is all wasteful however, instead you would be better with static methods, and something more like a singleton pattern e.g.:
UOM::Something();
I leave it as a task for you to learn what a singleton is, and what scope is, these are fundamental tennets of PHP, and you should not claim to know PHP without knowing about scope. The best way of putting it is when in everyday conversation, it is called context, the global scope is tantamount to shouting in everyones ear at the same time. Everyone can access it, and its not something you want to pollute
I'm sorry if I seem a bit harsh, here's some articles that should help, they talk about scope, singletons and some other methods of doing it, like object factories
http://php.net/manual/en/language.variables.scope.php
http://www.homeandlearn.co.uk/php/php8p2.html
http://php.net/manual/en/language.oop5.patterns.php
I did not make my question clear when I initially posted but based on the conversation with Tom, I have agreed to repost this more clearly on Stack Overflow.

How to create write-once properties?

I'm stuck with a general OOP problem, and can't find the right way to phrase my question.
I want to create a class that gives me an object which I can write to once, persist it to storage and then be unable to change the properties. (for example: invoice information - once written to storage, this should be immutable). Not all information is available immediately, during the lifecycle of the object, information is added.
What I'd like to avoid is having exceptions flying out of setters when trying to write, because it feels like you're offering a contract you don't intend to keep.
Here are some ideas I've considered so far:
Pass in any write-information in the constructor. Constructor throws exception if the data is already present.
Create multiple classes in an inheritance tree, with each class representing the entity at some stage of its lifecycle, with appropriate setters where needed. Add a colletive interface for all the read operations.
Silently discarding any inappropriate writes.
My thoughts on these:
1. Makes the constructor highly unstable, generally a bad idea.
2. Explosion of complexity, and doesn't solve the problem completely (you can call the setter twice in a row, within the same request)
3. Easy, but same problem as with the exceptions; it's all a big deception towards your clients.
(Just FYI: I'm working in PHP5 at the moment - although I suspect this to be a generic problem)
Interesting problem. I think your best choice was #1, but I'm not sure I'd do it in the constructor. That way the client code can choose what it wants to do with the exception (suppress them, handle them, pass them up to the caller, etc...). And if you don't like exceptions, you could move the writing to a write() method that returns true if the write was successful and false otherwise.

ideas for simple objects for day to day web-dev use?

Dang-I know this is a subjective question so will probably get booted off/locked, but I'll try anyway, because I don't know where else to ask (feel free to point me to a better place to ask this!)
I'm just wrapping my head around oop with PHP, but I'm still not using frameworks or anything.
I'd like to create several small simple objects that I could use in my own websites to better get a feel for them.
Can anyone recommend a list or a resource that could point me to say 10 day-to-day objects that people would use in basic websites?
The reason I'm asking is because I'm confusing myself a bit. For example, I was thinking of a "database connection" object, but then I'm just thinking that is just a function, and not really an "object"??
So the question is:
What are some examples of objects used in basic PHP websites (not including "shopping cart" type websites)
Thanks!
Here's a few basic reusable objects you might have:
Session (identified by a cookie, stored server side)
User (username, password, etc.)
DBConnection (yes, this can be an object)
Comment (allow users to comment on things)
It sounds like you want to start to build your own web framework, which is a decent way to learn. Don't reinvent the wheel though. For a production site, you're probably better off using an existing framework.
Since you said you don't want to glue HTML and CSS again, you don't try this:
Create a WebForm class. This class is a container of form elements. It has methods to add and remove form elements. It has a getHTML() method that writes the form so that the user can input data. The same object is when a POST is made. It has a method to validate the input of the user; it delegates the validation to every form element and then does some kind of global validation. It has a process method that processes the form. It is final and checks whether validation has passed. If it passed it calls an abstract protected method that actually does the form-specific processing (e.g. insert rows into the DB). The form may be stored in the stored in session, or it may be re-built everytime (if it is stored in the session, it's easier to make multi-page forms).
Create a BaseFormElement and then several child classes like EmailElement, PhoneElement etc. These have also a getHTML() method that is called by WebForm::getHTML() and that prints the specific element. They have a validate() method that is called by WebForm::validate() and a getData() method that returns the properly validated and processed data of that element.
These are just some ideas. Some things may not make sense :p
I'd say database access would be the first most likely object - encapsulate your most common SQL requests into one class. If you make them abstract enough, you can use them for a wide variety of data access situations.
The way to think about class design/usage is to think of the class responsibility. You should be able to describe the class purpose in a short sentence (shorter than this...) i.e for database access object, you might say:
"provides API for common data access tasks"
If any of the methods in your data access class do something other than that, then you know they belong somewhere else.

I'm new to OOP/PHP. What's the practicality of visibility and extensibility in classes?

I'm obviously brand new to these concepts. I just don't understand why you would limit access to properties or methods. It seems that you would just write the code according to intended results. Why would you create a private method instead of simply not calling that method? Is it for iterative object creation (if I'm stating that correctly), a multiple developer situation (don't mess up other people's work), or just so you don't mess up your own work accidentally?
Your last two points are quite accurate - you don't need multiple developers to have your stuff messed with. If you work on a project long enough, you'll realize you've forgotten much of what you did at the beginning.
One of the most important reasons for hiding something is so that you can safely change it later. If a field is public, and several months later you want to change it so that every time the field changes, something else happens, you're in trouble. Because it was public, there's no way to know or remember how many other places accessed that field directly. If it's private, you have a guarantee that it isn't being touched outside of this class. You likely have a public method wrapped around it, and you can easily change the behavior of that method.
In general, more you things make public, the more you have to worry about compatibility with other code.
We create private methods so that consumers of our classes don't have to care about implementation details - they can focus on the few nifty things our classes provide for them.
Moreover, we're obligated to consider every possible use of public methods. By making methods private, we reduce the number of features a class has to support, and we have more freedom to change them.
Say you have a Queue class - every time a caller adds an item to the queue, it may be necessary to to increase the queue's capacity. Because of the underlying implementation, setting the capacity isn't trivial, so you break it out into a separate function to improve the readability of your Enqueue function. Since callers don't care about a queue's capacity (you're handling it for them), you can make the method private: callers don't get distracted by superfluous methods, you don't have to worry that callers will do ridiculous things to the capacity, and you can change the implementation any time you like without breaking code that uses your class (as long as it still sets the capacity within the limited use cases defined by your class).
It all comes down to encapsulation. This means hiding the insides of the class and just caring about what it does. If you want to have a credit card processing class, you don't really care 'how' it processes the credit card. You just want to be able to go: $creditCardProcessor->charge(10.99, $creditCardNumber); and expect it to work.
By making some methods public and others private or protected, we leave an entry way for others so they know where it is safe to call code from. The public methods and variables are called an 'interface'.
For any class, you have an implementation. This is how the class carries out its duty. If it is a smoothie making class, how the class adds the ingredients, what ingredients it adds, etc are all part of the implementation. The outside code shouldn't know and/or care about the implementation.
The other side of the class it its interface. The interface is the public methods that the developer of the class intended to be called by outside code. This means that you should be able to call any public method and it will work properly.
There are several reasons for using encapsulation, one of the strongest is: Imagine using a large, complicated library written by someone else. If every object was unprotected you could unknowingly be accessing or changing values that the developer never intended to be manipulated in that way.
Hiding data makes the program easier to conceptualize and easier to implement.
It's all about encapsulation. Methods are private that do the inner grunt work while exposing graceful functions that make things easy. E.g. you might have an $product->insert() function that utilizes 4 inner functions to validate a singleton db object, make the query safe, etc - those are inner functions that don't need to be exposed and if called, might mess up other structures or flows you, the developer, have put in place.
a multiple developer situation (don't
mess up other people's work), or just
so you don't mess up your own work
accidentally?
Mainly these two things. Making a method public says "this is how the class is supposed to be used by its clients", making it private says "this is an implementation detail that may change without warning and which clients should not care about" AND forces clients to follow that advice.
A class with a few, well documented public methods is much easier to use by someone who's not familiar with it (which may well be its original author, looking at it for the first time in 6 months) than one where everything is public, including all the little implementation details that you don't care about.
It makes collaboration easier, you tell the users of your classes what parts should not change so often and you can guarantee that your object will be in a meaningful state if they use only public methods.
It does not need to be so strict as distinguishing between private/public/whatever (I mean enforced by the language). For example, in Python, this is accomplished by a naming convention. You know you shouldn't mess with anything marked as not public.
For example - private/protected method may be part of some class which is called in another (public) method. If that part is called in more public methods, it makes sense. And yet you don't want these methods to be called anywhere else.
It's quite the same with class properties. Yes, you can write all-public classes, but whats the fun in that?

How can I make my objects/classes more portable?

From my basic understanding in Object Oriented coding, PHP in my case, you want to make all your classes pretty much independent of one another. I have just started my object oriented application so it is a great time for me to make changes in it's early stages.
Here is my situation where I break this rule or whatever you want to call it.
I have a sessions class that has a set method which lets me set variables to a php session and I have a view method which let's me view the value of a value that has already been set using the set method. So far it probably sounds OK but then on every page of my site I need to access session data or the session objects I should say. But then besides every page using the session objects, I also use them in all my classes that need the session value. I believe this is where I have messed up, because now all these other classes rely on the session class.
Any ideas on if this is wrong and if it is, what are some ways I can avoid it but still have access to the session data in the other classes and still have my classes be portable plug-n-play into other future applications?
This kind of relationship is called dependencies or coupling. You generally want to reduce coupling in any application (Object oriented or not). Just how to do it is perhaps the most important skill of a programmer, and can't really be summarised into a few rules.
However, at the most basic, you should try to distinguish between essential dependencies and accidental dependencies. The former is an un-solveable problem, so you shouldn't try. For example, if all your pages need access to the session, then you really can't help giving them that. But if they only need it some times, than you could try to factor your application so that this is addressed.
Another important point is to minimise the interfaces between components. If x is a subset of X and Y relies on x, then you shouldn't pass X. This is often a place where there is room for improvement.
Think about what those other classes need in order to function in terms of your domain model. Session data is an implementation detail that shouldn't affect how you design your other classes. The session object might have 100 properties, but not every class needs all 100 of those properties to work. They don't need to know if that data was persisted in sessions, cookies, flat-files, databases, or on a satellite outside earth.
A great resource I've found useful while designing classes is this book, and specifically chapter 6, "Working Classes" for your question.
You could add one level of abstraction making it WorkingClass > StoringMapper > Session, with WorkingClass only calling StoringMapper. As such, you could easily "map" the storing process to any other class than Session (for example DatabaseSession) without any changes to WorkingClass.
I've written some code for it in response to another question: Advice on framework design
Generally, one class using another is pure basic OO and what you'll want. Using Interfaces is a way to have your concrete logic isolated while letting other classes use this component in a uniform way. A simple and common way is to use a Factory or Abstract Factory instead of directly calling constructors. You should also have a look at the Inversion of Control and Dependency Injection (DI) paradigms. Here's a rudimentary example that could help you with your problem (but be aware, the author mixes up between Factories and DI).
A not to complex solution would be to extract an interface from your Session class. Think of what a caller would need from a session object. Then realize the interface in your class. You'll maybe want to make this class a Singleton (a class for which only one realization exists at runtime). Then, create a factory that instanciates your script's components. Pass the session instance to the components in the factoring method.

Categories