How should I make my classes interact - php

I've been writing PHP within WordPress for a while, but I'm pretty new to straight PHP applications. I'm writing a little application that uses a few different APIs to do cross posting.
I've written the classes, but I'm not sure of the best way to have them interact.
A bit of background on the classes and their functionality. I've got a class for each API (Reddit, Imgur, Twitter), a class with some Curl helper functions, a class that carries out the process. I don't think I'll ever need more than one instance of any of these current classes. Nor will they ever need to be extended.
From what I've read, I've got a few options:
Instantiate each class as a global variable (I've heard I should avoid this)
Make the classes singletons (Also heard I maybe should avoid this)
Static methods - though some of the classes need to be instantiated and I'm not sure how that would work.
Those are the methods I've heard of. I'm expecting the answer will be none of the above. How do frameworks like Laravel do this?
This might be subjective, but I'm sure I'll learn something about patterns.
Edit: I probably should add some examples of the types of interactions required.
An API class using the CurlHelper class (I'm currently using a static method: $post_string = CurlHelper::createPostString( $post_data );)
Generating a title in one class for use when cross posting to each API

Related

PHP OOP implementation idea

I am looking to just get an understanding on how you guys would implement the following.
I think I have a reasonable understanding of OOP. If I have a website and a user account can be created for this website. I understand that I can create a user class that will handle the creation of this user by passing the relevant information through to the class.
If I have to make a CuRL post to pass some information through to a third party. would it make sense to create a CuRL class for this process that the user class can instantiate, also allowing for another class to post data through as well rather than creating a static function in global space or a curl function within each class that requires this function?
Another issue I have with my understanding of OOP, is if I have many similar functions that help to perform what is required. I will tend to bunch these all into one class (utils class?). This could range from passing in an array of data to output as a select element to passing user entered data through to validate and sanitize as required and return.
I think I am just looking for clarity on what is a good implementation of code with regard to OOP. Is it OK to have floating/static functions in global space working along side classes (Can that still be considered as OOP) or should everything I code be grouped as an object within a class that it would best fit?
I hope that makes sense?
Thanks
The concept behind OOP is to structure and divide responsibilities among various classes.
Models
There are various building stones, that are normally used when you consider different aspects of your application. For instance, a User class would often be considered a Model and be tied into an ORM.
The responsibility of a Model is to map the data stored in a database to the data stored in memory by PHP (or any other language). In many cases Models can also instantiate and register themselves in the database. Which is what you're looking for. Laravel's Eloquent ORM is a good example of an ORM which supports this.
cURL helper
Depending on your own opinion and the exact use case, both of your suggestions may be useful. I myself try to divide the responsibilities of each class as much as possible, this is to reach the purpose of a divided responsibility.
So I would create a helper class which can handle communication through cURL, which you can then call from various classes. I would even take if to a further level and create a Transport interface which cURL can implement. This would allow me to easily swap cURL with another transport layer, without having to change all the objects which depends on cURL.
Concept example:
<?php
interface Transport {
const POST = 'post';
public static postRequest($url, $data);
protected static processRequest($method, $url, $data);
}
class cURL implements Transport
{
public static postRequest($url, $data) {
return self::processRequest(self::POST, $url, $data);
}
protected static processRequest($method, $url, $data) {
// Implement method
}
}
This cURL example ties well together with your third question. These are often called helper functions or helper methods. Depending on the code design your choose or the design of the framework you use, the way helper methods are called can vary.
I use Laravel which provides static methods. You can see some examples for the Hash and Auth helpers here.
OOP is not Functional programming
Global function is not a part of OOP. But there's no one to tell you whether this is good or bad practice, that is up to yourself to decide, whether this approach will work the best for your use case. Obviously it requires a certain amount of experience to consider all aspects of the chosen design patterns, but experience comes with time.
To use Laravel as an example again, they do provide some global functions that adhere to old fashioned PHP functional programming style. But the framework is mainly OO.
My suggestion to you
It sounds like you need a boilerplate for what you intend to build. I would suggest that you consider a framework to use, since frameworks will often answer the questions you're asked here. Both in terms of conventions and object responsibilities.
You could check this article for suggestions on PHP frameworks to use.

How to use one object in another class : PHP framework

This is my current system for a framework that I'm making:
I create an object upon a request to access a non-existing property, that has the name of an existing class through the __get function defined in the Core class. The Core class extends every class.
So it works like this:
class Someclass extends Core
{
public function classmethod()
{
$this->otherclass->method();
}
}
This works exactly how I want it to work. However, I have no idea (after a lot of frustration) how to edit/create properties of the object, using this system.
So something like this would't work.
$this->view->somevar = "newvalue"; // this doesn't work.
I guess it has to do something with the __set function, but I failed to find out.
I received the following suggestions how to tackle this problem:
Dependency injection, Namespaces, Singleton pattern.
I would love to see how to implement what I'm trying to do using one of these patterns.
I have no idea which to choose in order to achieve my simple problem: Use objects in other classes, so i don't need to put anything into __construct's parameters or using global variables.
I am using __autoload.
I hope i can tackle this problem with your help.
First of all, the architecture you're attempting is extremly bad. Aparently you are using "magic" to create objects attached as properties to other objects. Which is bad, because if you use _get/_set, you will end up in problems sooner rather than later. Also extending from a common parent is a bad thing because it generates huge inheritance trees, and it allows most of the objects to have more than one responsability.
Before starting a framework, you might want to look over: SOLID
Now coming back to your question, if you use __get for getting a value, you can as well use __set for setting a value.
__construct method is there in order to allow you to initialize the object with all the data it needs in order to fulfill his sole purpose. Avoiding the __construct is kinda stupid, and defeats the purpose. You might want to pay attention to the D in SOLID in order to see what Dependency Inversion really is and to understand it.
Using __set loses completely the ability to typehint interfaces and so on. Therefore the code can become really buggy and ijcredibly hard to follow, since the flow is not so well defined, and the allocation is done in the back via magic. Also i can come up with 1 million other reason for which the architecture you are trying to use is wrong, but i will leave that for another time.

Static methods or not?

I need to develop a small CMS using PHP, and right now I'm trying to figure out the structure.
The CMS will be generated using a set of functions. Things like database functions, caching thingies, internationalization and stuff like this.
I was thinking to do it like this:
make the functions non-static methods part of a big "site" class; that way I could run multiple instances of that class. Not sure I would need to do that though..
or split the functions into separate classes with static methods
The main problem here is that the CMS should be able to manage multiple small sites, not just one. So either I make all methods static and add a "site switch" function, or make them normal objects which I instantiate based on the site which I want to manage
Which of these would be the best option?
Static methods are generally bad practice. They introduce a lot of potential issues.
1) They introduce hidden dependencies. Code which arbitrarily calls foo::bar() has a dependency on foo and cannot run without foo being defined. The object using foo::bar() will construct correctly but won't be usable if foo is not defined.
2) Statics are globals. Global state is very bad, anything can change the code and its state is unknown. You sacrifice the power and control achieved by OOP encapsulation by using static methods.
3) It's impossible to substitute the functions for a different version
4) It makes unit testing impossible.
For more detailed information and code examples, see this article and this article
I'd definitely suggest using static classes for this job. Going this route will create a pseudo namespace for all of your functions so you don't have to worry about conflicting function names, etc, and it also prevents you from having to pass around an instance of your helper class just to call one of your helper functions.

Drawbacks of static methods in PHP

In a theoretical database access class, I found that there are quite a few helper functions that I use in the class, which have nothing to do the class's instance (and others, that could be manipulated to be unrelated to the class's instance using dependency injection).
For example, I have a function that gets a string between two other strings in a variable. I've been thinking of moving that to a String_Helper class, or something of the sort. This function has already been made static.
Also, I have a function that queries a database, query($sql). The connection details are provided by the instance, but I've been considering making it static, and using query($sql, $connection). Developers would then be able to call it statically and not need to instantiate the database class at all.
For me, the questions are:
Is it worth it to do something like this? Functions like the query function make me wonder if this is not just me trying to make everything as static as possible, without any real need to. Under what circumstances would you consider this useful?
I know static functions are harder to test, but if I make sure that their code is completely dependency free (or uses dependency injection where necessary), then they're just as easy to test as everything else, surely?
It isn't a concern at the moment, but if, in the future, I decided to extend the classes with the static functions, it would be impossible for me to make the current code use my extended functions. I've thought of Singletons, but the same problem arises: the code would be calling Singleton_Class::getInstance(), and not My_Extended_Singleton_Class::getInstance(). Dependency Injection seems to be the only way to solve this issue, but it might lead to a clunkier API, as every dependency has to be given to an object on __construct().
I have a container class, which holds certain pieces of information statically so that they can be accessed anywhere in the script (global scope). If I can't use static functions or singletons, a class that contained instances of different variables would be great. One could use for example Container::$objects['MyClass'] = $MyClass_object;, and then the rest of the code could just access Container::$objects['MyClass']. If I extended the MyClass class, I could use Container::$objects['MyClass'] = $MyExtendedClass_object;, and the code that used Container::$objects['MyClass'] would use MyExtendedClass, rather than MyClass. This is by far the best way to do it, in my opinion, but I'd like to know what you think about it.
Ok, let me answer these one by one...
1. Is it worth doing something like this
Yes and no. Splitting out the helper functions into their own classes is a good idea. It keeps the "scope" of each of the classes rigidly defined, and you don't get creap. However, don't make a method static just because you can. The query method is there to make your life easier by managing the connection, so why would you want to lose that benefit?
2. They are harder to test
They are not harder to test. Static methods that depend on state are harder to test (that access static member variables or global variables). But static methods in general are just as easy to test as instance methods (in fact, they can be easier since you don't need to worry about instantiation).
3. Extending the classes
This is a valid concern. If you put String_Helper::foo() in the class itself, you'll run into issues. But an option would be to set the name of the string helper as a class variable. So you could then do {$this->stringHelper}::foo() (note, PHP 5.3 only). That way to override the class, all you need to do is change the string helper class in that instance. The Lithium framework does this a lot...
4. Global Registry
I would stay away from this. You're basically just making every class a singleton without enforcing it. Testing will be a nightmare since you're now dependent on global scope. Instead, I'd create a registry object and pass it to classes via the constructor (Dependency Injection). You still accomplish the same thing since you have a store for the objects/classes, but you're no longer dependent on a global scope. This makes testing much easier.
In general
When you're looking at doing things like this, I like to stop when I hit questions like this. Stop and sit down and think *What actual problem am I trying to solve?". Enumerate the problem explicitly. Then pull our your supposed solutions and see if they actually solve them. If they do, then think about the future and if those solutions are really maintainable in the long run (Both from a bug fix standpoint, and with respect to feature additions). Only if you're happy with both of those answers should you even consider doing it. Oh, and also remember to keep it simple. Programming is not about making the most complex, most clever or most amazing solution. It's about making the simplest solution that solves the problem...
I hope that helps...
Good Luck!

Confused About Objects and Classes in CodeIgniter?

I’m fairly new to CodeIgniter and have a question. I’m a bit confused about Classes, Libraries and Objects.
Does CodeIgniter replace the normal PHP way of usings objects i.e. $var = new car(); with libraries i.e. $this->load->library('some_library'); $this->some_library->some_function(); ?
If both are valid, is there a difference? If so, what are the differences and when do I use one over the other? Which is more common/proper?
I am asking because I created a class, but I'm not certain what is the correct manner in which to instantiate it.
Thanks in advance
I am not familiar with CodeIgnitier. But familiar with other PHP frameworks. Most of frameworks use this way for performance improvements, registering things, executing certain events, and making things simpler for developer...
For example if you want to create class "car" with is somewhere in library directory you would have to include the file first before you can create object of that class (miltiple lines of code, more room for error). The framework will create the class and includes related files in 1 line of code (easier and safer).
Framework way also works as a factory. Instead of recreating an object, it will create object only once and every time you call the method again it will return the reference to existing object.
More things are happening behind the scenes when you use framework. Things are getting registered, etc...
CI doesn't replace class behavior per se, it simply adds functionality that allows access to custom libraries/models/views as singleton objects via the core object for simplicity.
Nothing is stopping you from creating (as I have in one of my projects) additional files with classes for non-singleton entities and require them in a model for further use. On hindsight, I should probably have used helpers for this.
What the loader ($this->load) class does, among other things, is it creates a single object of the specified class (model, library or view - not helpers though, see below) and attaches it as a property of the core class that is normally accessible via $this.
Helpers are a bit different. They are not attached, but instead simply 'read' into the global namespace from the point where they are loaded.
To answer your question, it would be more proper to use the loader class in instances where you don't need more than one instance of a class created. If you need 'entity' classes, your best CI-compliant bet would be to create them as helpers.
Given only this context, this looks like Inversion of Control (maybe I'm wrong, I haven't looked too closely at CodeIgniter).
You don't want to rely on the type car as in new car(). What if later you want to make $var a racecar? $var can still do the same things, but it is forced to be a car because you constructed it directly. Or what if you are testing this class, but car is some complex object which calls some external service. You want to test your logic, but don't care if the car service isn't working. So you should be able to change $var to actually load a mockcar. You can't do that if you do $var = new car().
What is Inversion of Control?

Categories