While creating classes, I followed OO conventions and declared all class variables before using them:
class myClass {
private $property1, $property2, ...;
public __constructor() {
$this->property1 = $this->property2 = NULL;
}
}
But I realized that PHP is scripting language and not following OO concepts strictly, so we can 'generate' class property dynamically:
class myClass {
public __constructor() {
$this->fields = $this->db->getFields(TABLE_NAME);
foreach($this->fields as $fld) {
$this->{$fld} = NULL;
}
}
}
Is this a good approach ?
I think dynamically generated properties would have public access by default, so that could be one disadvantage and such automation could be one advantage.
Is there any difference in terms of performance ?
You're not encouraged to do so, but in some cases you just need to (like in ORM, which you seem to be writing). Classes should have clean interfaces (programmer needs to know what can he do with your class).
But there's a better way of handling these cases (at least, it seems better for me). Prepare an associative array of data in your class and use __get method. It can be even better for an ORM (you may implement lazy loading, etc.).
If you're writing code (library) that many users should use, it would be better to be strict in the definition of your API. so that there would be less mess when implementing it. but if you're using it for a single case it wouldn't be so bad, in fact it could provide much flexibility.
This depends on your situation. This is a common practice when you have have data containers that are mapped directly to tables (or some other structure). Most commonly used in ORMs because the columns are determined at run time and you don't need to define a container class for each of your tables.
It all depends on how you want to make use of those publicly available variables. For example in frameworks like Symfony make very good use of them. all dynamic class variable are can be made available outside the class in templates and such.
So it can be a good practice if you are creative with them
Related
I'm wanting to gauge people's opinions on the use of static classes instead of namespaces. I come from a C++ background and am quite fond of its syntax and how it lets you structure code. I recently decided I needed to group my code into logical units instead of just files. For instance I prefer calls like User::login to user_login. So, I did a bit of googling and was relieved to find that PHP has namespaces. My relief didn't last long though, I really don't like the syntax; it adds more mess to my function calls. So, at the moment I'm using static classes to simulate namespaces. Are there any downsides to this?
I found a similar question at PHP Namespaces vs Classes with static functions but there wasn't a whole lot of discussion.
Also, is there a way to avoid the following situation:
class Test {
public static void myFunc() {
Test::myOtherFunc();
}
public static void myOtherFunc() {
}
}
I assumed it would be ok to call functions in the same class without specifying the name, but apparently not. Are there any workarounds for that (for instance in C++ there the using keyword).
Coincidentally I've actually been moving into the exact opposite direction:
Use namespaces to organize domain classes (or functions)
Use dependency injection where I would have otherwise used static classes
The thing with static classes to simulate namespaces is that you can't organize them across multiple files, everything has to be defined inside one file; this may well be up to personal taste.
The other thing about static classes is that you start without any state and slowly some state management creeps in and you end up with some weird lock-in dependency. State should be reserved for instances. Currently my only notable static class is the site-wide configuration.
Lastly, self referencing in static classes is explicit, whereas in namespaces it works exactly like C++ would: you specify the function name and it gets looked up within the namespace first.
If you look from the standpoint of code structure, there is no difference between static class method and namespaced function. They both end up in global scope. Only difference is, that, with static class method, you are trying to fake OOP.
Therefor it is better to use namespaced functions, if what you really need are standalone/utility functions. Namespaces are for grouping thing (both function and classes).
As for you User::login() example, it would be a bad practices. Instead you should have a real object, which is able to capable of containing state.
$mapper = new UserMapper;
$user = new User;
$user->setNickname( $name );
$mapper->fetch( $user );
if ( $user->hasPassword( $password ) )
{
$user->setLastLogin( time() );
}
else
{
// log the access attempt
// set error state
}
$mapper->save( $user );
The bottom line is this: if you are using static structures ( functions or methods ), it is not OOP. You are just faking it. Instead you should use real OOP, with dependency injection.
If your code uses static methods and variables all over the place, it causes tight coupling between classes, add global state and makes harder to maintain and test your codebase. And this is not PHP specific.
I recently started learning the basics of OOP in PHP.
I am new to a whole lot of concepts.
In the traditional procedural way of doing things, if I had a repetitive task, I wrote a function and called it each time.
Since this seems to be a regular occurence, I created a small library of 5-10 functions, which I included in my procedural projects and used.
In OOP, what is the valid way of using your functions and having them accessible from all objects?
To make things closer to the real world, I created a thumbnail class, that takes an image filename as an argument and can perform some operations on it.
In procedural programming. when I had a function for creating thumbnails, I also had a function to create a random md5 string, check a given folder if said string existed, and repeat if it did, so I could generate a unique name for my thumbnails before saving them.
But if I wanted to generate another unique name for another purpose, say saving a text file, I could call that function again.
So, long story short, what is the valid OOP way to have the method randomise_and_check($filename) (and all other methods in my library) accessible from all the objects in my application?
Great question. The first thing you want to do is identify the primary objects you will be working with. An easy way to do this is to identify all the nouns related to your project. In your example it sounds like you will be working with images and strings, from this we can create two classes which will contain related attributes (functions, member variables, etc). And as you wisely mentioned, we need to ensure that the algorithms you are converting into OOP can be called from any context, so we try to keep them abstract as possible (within reason).
So for your specific situation I would suggest something like:
// Good object reference, abstract enough to cover any type of image
// But specific enough to provide semantic API calls
class Image
{
// Using your example, but to ensure you follow the DRY principle
// (Don't repeat yourself) this method should be broken up into two
// separate methods
public static function randomise_and_check($fileUri)
{
// Your code here
....
// Example of call to another class from within this class
$hash = String::generateHash();
}
}
// Very abstract, but allows this class to grow over time, by adding more
// string related methods
class String
{
public static function generateHash()
{
return md5(rand());
}
}
// Calling code example
$imageStats = Image::radomise_and_check($fileUri);
There are several other approaches and ideas that can be employed, such as whether or not to instantiate objects, or whether we should create a parent class from which we can extend, but these concepts will become evident over time and with practice. I think the code snippet provided should give you a good idea what you can do to make the jump from procedural to OOP. And, as always, don't forget to read the docs for more info.
-- Update --
Adding an OOP example:
class Image
{
protected $sourceUri;
public function setSourceUri($sourceUri)
{
$this->sourceUri = $sourceUri;
}
public function generateThumb()
{
return YourGenerator::resize($this->getSourceUri);
}
}
$image = new Image();
$image->setSourceUri($imageUri);
$thumbnail = $image->generateThumbnail();
The way I see it, you have two options:
Don't worry about cramming yourself into OOP and just make them standard, global functions in some utilities.php file you include wherever you want to use it. This is my preferred method.
If you take the more OOP approach, you could make them static functions ("methods") in some utilities class. From the PHP documentation:
<?php
class Foo {
public static function aStaticMethod() {
// ...
}
}
Foo::aStaticMethod();
$classname = 'Foo';
$classname::aStaticMethod(); // As of PHP 5.3.0
?>
Create an (abstract) Util-class with static functions:
example from my Util class:
abstract Class Util{
public static function dump($object){
echo '<pre class=\"dump\">' . print_r($object, true) . '</pre>';
}
}
How to use:
<?
$object = new Whatever();
//what's in the object?
Util::dump($object);
?>
For a beginner, OOP development is not all that different from procedural (once you master the basic concepts it gets quite a bit different, but that's not important to learning the basics).
You deal in OO concepts all the time, you just don't realize it. When you click on a file in your file manager, and manipulate that file.. you're using Object Oriented concepts. The file has attributes (size, type, read-only, etc..) and things you can do with it (open, copy, delete).
You just apply those concepts to development by creating objects that have properties and things you can do with it (methods).
In the OOP world, you don't typically make things available to everything else. OOP is all about "encapsulation", which is limiting access to only that which is needed. Why would you make a "haircut" method available to an orange juice object? You wouldn't. You only make the "haircut" method available to objects that need haircuts.
Writing reusable OO software is very difficult. Even professionals can't get it right a lot of the time. It requires a mixture of experience, training, practice, and frankly luck in some cases.
You should read about Dependency Injection as it seems to apply to your specific problem. Basically, you have an object that depends on some abstraction, maybe the "Image Library" functionality. In your controller, you would create an instance of the "Image Library" object and inject that dependency into whatever other objects required it.
That is, you need to stop thinking on the global scope altogether. Instead, you have to compartmentalize functionailties in a sane way and tie them together. Basically, objects should only know about as little as they need to know (also look up Law of Demeter and SOLID). I reiterate, this is tough to do correctly, and most of the time you can still have an application that works beautifully even if it's done incorrectly.
If you want to be very strict about this you should apply this line of thinking to everything, but if you have a function that wraps something very simple like return isset($_POST[$key]) ? $_POST[$key] : $default; I see no real harm in creating a global function for that. You could create an HttpPost wrapper class, but that is overkill in most circumstances IMO.
The short answer: use ordinary function. OOP encourages you to think about data and associated routines, using static functions instead of ordinary does not make your program more object-oriented. Following the single programming paradigm is not practical, combine them when you see that this will make your program cleaner.
I'm writing a bunch of generic-but-related functions to be used by different objects. I want to group the functions, but am not sure if I should put them in a class or simply a flat library file.
Treating them like a class doesn't seem right, as there is no one kind of object that will use them and such a class containing all these functions may not necessarily have any properties.
Treating them as a flat library file seems too simple, for lack of a better word.
What is the best practice for this?
Check out namespaces:
http://www.php.net/manual/en/language.namespaces.rationale.php
Wrapping them in a useless class is a workaround implementation of the concept of a namespace. This concept allows you to avoid collisions with other functions in large projects or plugin/module type deployments.
EDIT
Stuck with PHP 5.2?
There's nothing wrong with using a separate file(s) to organize utility functions. Just be sure to document them with comments so you don't end up with bunchafunctions.php, a 20,000 file of procedural code of dubious purpose.
There's also nothing wrong with prefixes. Using prefixes is another way to organize like-purpose functions, but be sure to avoid these "pseudo-namespaces" already reserved by the language. Specifically, "__" is reserved as a prefix by PHP [reference]. To be extra careful, you can also wrap your function declarations in function_exists checks, if you're concerned about conflicting functions from other libraries:
if (!function_exists('myFunction')) {
function myFunction() {
//code
}
}
You can also re-consider your object structure, maybe these utility functions would be more appropriate as methods in a base class that all the other objects can extend. Take a look at inheritance: http://www.php.net/manual/en/language.oop5.inheritance.php. The base class pattern is a common and very useful one:
abstract class baseObject {
protected function doSomething () {
print 'foo bar';
}
public function getSomething () {
return 'bar foo';
}
}
class foo extends baseObject {
public function bar () {
$this->doSomething();
}
}
$myObject = new foo();
$myObject->bar();
echo $myObject->getSomething();
You can experiment with the above code here: http://codepad.org/neRtgkcQ
I would usually stick them in a class anyway and mark the methods static. You might call it a static class, even though PHP actually has no such thing (you can't put the static keyword in front of a class). It's still better than having the functions globally because you avoid possible naming conflicts. The class becomes a sort of namespace, but PHP also has its own namespace which may be better suited to your purpose.
You might even find later that there are indeed properties you can add, even if they too are static, such as lazy-loaded helper objects, cached information, etc.
I'd use classes with static methods in such case:
class Tools {
static public function myMethod() {
return 1*1;
}
}
echo Tools::myMethod();
EDIT
As already mentioned by Chris and yes123: if the hoster already runs PHP 5.3+, you should consider using namespace. I'd recommend a read of Matthew Weier O'Phinney's article Why PHP Namespaces Matter, if you're not sure if it's worth switching to namespaces.
EDIT
Even though the ones generalizing usage of static methods as "bad practice" or "nonsense" did not explain why they consider it to be as such - which imo would've been more constructive - they still made me rethinking and rereading.
The typical arguments will be, that static methods can create dependencies and because of that can make unit testing and class renaming impossible.
If unit testing isn't used at all (maybe programming for home/personal use, or low-budget projects, where no one is willing to pay the extra costs of unit testing implementations) this argument becomes obsolete, of course.
Even if unit testing is used, creation of static methods dependencies can be avoided by using $var::myMethod(). So you still could use mocks and rename the class...
Nevertheless I came to the conclusion that my answer is way too generalized.
I think I better should've wrote: It depends.
As this most likely would result in an open ended debate of pros and cons of all the different solutions technically possible, and of dozens of possible scenarios and environments, I'm not willing going into this.
I upvoted Chris' answer now. It already covers most technical possibilities and should serve you well.
Treating them as a class does give you the benefit of a namespace, though you could achieve the same thing by prefixing them like PHP does with the array_* functions. Since you don't have any properties, that basically implies that all your methods are static (as Class::method()). This isn't an uncommon practice in Java.
By using a class, you also have the ability, if necessary, to inherit from a parent class or interface. An example of this might be class constants defined for error codes your functions might return.
EDIT: If PHP 5.3+ is available, the Namespace feature is ideal. However, PHP versions still lag in a lot of hosts and servers, especially those running enterprise-stable Linux distributions.
I've seen it a few different ways, all have their warts but all worked for the particular project in which they were utilized.
one file with all of the functions
one file with each function as its own class
one massive utilities class with all of the methods
one utils.php file that includes files in utils folder with each
function in its own file
Yes, it's OK formally... As any class is methods + properties. But when you pack in class just some functions -- it`s become not ideal OOP. If you have bunch of functions, that groupped, but not used some class variables -- it' seems, that you have somewhere a design problem.
My current feeling here is "Huston, we have a problem".
If you use exactly functions, there one reason to wrap them in static class - autoloader.
Of course, it creates high coupling, and it's may to be bad for testing (not always), but... Simple functions are not better than static class in this case :) Same high coupling, etc.
In ideal OOP architecture, all functions will be methods of some objects. It's just utopia, but we should to build architecture as close as we can to ideal.
Writing a bunch of "generic-but-related" functions is usually bad idea. Most likely you don't see problem clear enough to create proper objects.
It is bad idea not because it is "not ideal OOP". It is not OOP at all.
"The base class pattern" brought by Chris is another bad idea - google for: "favor composition over inheritance".
"beeing extra careful" with function_exists('myFunction') is not but idea. It is a nightmare.
This kind of code is currently avoided even in modern javascript...
I am currently working on a PHP project which includes extensive database usage. The basics are: I have a PDOFactory class which follows the Factory pattern and an abstract SQL class with static methods (just a container for those methods) which in turn talks to PDOFactory
As I said, the project involves extensive database usage, so the SQL class will contain numerous methods. However, they could be easily grouped, depending on what they deal with (i.e. session storage, user logging on/off, etc.). That would make the SQL class much easier to maintain and so on and forth. And here comes the big question: Can I have the source of the class contents spread across many files? There could be (at least) two possible solutions to this problem:
Multiple inheritance, i.e. having classes SQLSession, SQLUser, SQLblahblah and making the SQL class inherit all of them.
C++-like pre-processor* directives, i.e. #include SQLSession.php; or something like that.
I know there is no multiple inheritance in PHP, so that rules out option No. 1. Is option No. 2 even possible? Or does anybody know of better solutions to this problem?
*Or actually pre-pre-processor directives, since PHP is a pre-processor. :)
EDIT:
Here's an attempt to answer this question, based on Kalium's suggestion. It's a mess to read, but it works. However, I'm gonna stick with Bill's method as it's way cleaner.
class SQL {
private static $oInstance = false;
public static function getInstance()
{
if( self::$oInstance == false )
{
self::$oInstance = new self();
}
return self::$oInstance;
}
public $SESSION;
private function __construct()
{
$this->SESSION = new SESSION;
}
}
// this would be in another file
class SESSION {
public function printOne()
{
echo "One";
}
}
SQL::getInstance()->SESSION->printOne(); // outputs "One"
?>
I think you may be approaching this wrong. That's certainly not the best way to go about it. Try breaking the many functions into smaller utility classes and then using those to composite a larger class.
Don't use static methods, as it makes it hard to use something else than the SQL class
Use small classes, which have a single responsibility.
I think you should use the Builder pattern for your SQL instead of a motley container of static methods.
No, there is no multiple inheritance in PHP. Use delegation instead.
No, you can't include files to define methods of a class. You can only include files in contexts where code is executing, not in the middle of a class definition:
<?php
include("define-functions.php"); // OK
class Foo
{
include("define-methods.php"); // ERROR
function foo()
{
include("method-body.php"); // OK
}
}
PHP Parse error: syntax error, unexpected T_INCLUDE, expecting T_FUNCTION
in foo.php on line 7
Re your comment:
Since you're committed to using only static methods, why bother with a class at all? Just define functions in the global scope. Then you can include() as many as you want:
<?php
include("SQLSession.php");
include("SQLUser.php");
include("SQLblahblah.php");
SQLSession.php:
<?php
function SQLSessionStart()
{
...
}
function SQLSessionEnd()
{
...
}
You don't have access to static class member data with this solution, but you can just use global variables.
to me, it sounds like you're trying to create a monolithic chunk of code, which is the exact opposite of class based OO code - I'd recommend following the DAO blueprint of the Java core patterns, and implementing it in PHP for what you want to do :) that should cover all you're questions
I need some advise on my PHP code organisation.
I need classes where I can store different functions, and I need access to those classes in different parts of my project. Making an object of this classes each time is too sadly, so I've found a two ways have to solve it.
First is to use static methods, like
class car {
public static $wheels_count = 4;
public static function change_wheels_count($new_count) {
car::$wheels_count = $new_count;
} }
Second is to use singleton pattern:
class Example {
// Hold an instance of the class
private static $instance;
// The singleton method
public static function singleton()
{
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
} }
But author of the article about singletons said, that if I have too much singletons in my code I should reconstruct it. But I need a lot of such classes.
Can anybody explain pros and cons of each way? Which is mostly used? Are there more beautiful ways?
See this excellent post:
Singleton Pattern vs Static Classes
More Resources:
How Bad Are Singletons?
Static DB class vs DB singleton object
When you say that you need to use a class of some sort to store functions, I am presuming that you'd normally be fine using plain functions but you do not want to pollute the global scope. This problem you will run into all the time in PHP.
If you are lucky to be working with PHP 5.3 you can use namespaces to pull the functions out of the global scope. Effectively, namespaces serve as a convenient way to auto-complete the prefixes you would normally have on functions to try and ensure their uniqueness. Because of this primitive implementation, there is no access control available for namespaces. If you wish to design an interface, you are out of luck, as all functions are globally accessible.
In this case, use a static class. No, it is certainly not the most beautiful solution but it is literally the best PHP can offer. With a static class you can effectively both prefix your functions for uniqueness and use access control.
Singletons are an object-oriented concept that solve a different problem. If your original design involves no objects, don't introduce them now.
That said, you have a function called change_wheels_count(). This function has a notion of state, and whenever you need state you need an object. I do not know if your code was just a quick example or your actual situation. If it was your actual situation, I would say you need neither a static class or a singleton.