(This is not an interface: I simply omitted the method bodies)
class _ {
protected $_data = array();
function __construct($data);
function set($name, $value);
function get($name);
function __set($name, $value);
function __get($name); //aliases for their respective non-magic methods.
# and some other generic methods
}
Essentially it's a class that provides a magical object-oriented reusable access layer to some data. I've considered DataLayer, DataObject and some others; I'd like to hear some suggestions from someone who's more terminologically savvy.
How about Dave ;)
Seriously though, what about DataAccess
Without knowing how the class is used and what data it's meant to wrap, it's hard to name it. "Wraps some data in magic OOP" is so generic that a meaningful class name is difficult.
If it's for sitting between the controller and the database, you could call it ActiveRecord.
If it really is just for providing some OOP syntactic sugar to an array(), you could simply use the built-in StdClass.
Failing that, given that the only purpose of the class seems to be to wrap an array, I'd be tempted to call it ArrayWrapper.
There's a class like that in Magento. Well, it's got a lot more stuff in it, but the philosophy is the same: add some magic method goodness to the rest of your classes via inheritance. They named it Varien_Object, Varien being the name of the company.
I've also got something like this in a custom framework I've helped build. It's just called Base.
I guess what I'm trying to say is... no matter what you call it, it wont help people understand what it does until they go through the code. Don't worry about it too much, by the time you're done it'll be buried so deep in your app that the only people that find it will be the kind that can grok what it does fairly quickly anyway
You could call it AccessLayer.
It really resembles KeyPairValue and if you with to make it more specialized in defining how Get would find its entries say using a Hash() function, then it's a Hashtable.
class KeyPairValue
class Hashtable
Now the question is why? Most SDKs would offer such data structures?
Try to use existing structures and not re-invent them.
Related
In my efforts to rewrite a past project of mine with OOP in mind, I have broken my code up into classes such as Devices, Facilities, etc.
Before moving to a more object oriented approach, I just stuck all of my helper functions in an included "functions.php" file. Using Devices as an example, would it be best to have a Devices class for my object specific properties/methods, then have a DeviceManager class to store functions like getDeviceByName, getDeviceByID, etc?
From what I am understanding, OOP is more about readability/manageability than anything else, why I assume the purpose would just be to have something like DeviceManager::GetDevice("Computer1") in place of GetDeviceByName("Computer1")
If you are thinking of using a class as a namespace then you can just as well use an actual namespace:
namespace MyCollectionOfFunctions;
function printMyName($name) {
echo $name;
}
And then you can use the functions like this:
use MyCollectionOfFunctions as fn;
echo fn\printMyName('Brett Powell');
There is nothing wrong with functions. Do not let anyone tell you that they belong is a class, as static methods. It can be done that way, but since we got namespaces there really is no reason for it.
In a OOP languages like C# or Java, you simply can't have functions outside a class, so there's no issue. That doesn't mean you're doing OOP, which is a mindset.
In PHP you can either put the relevant functions into a nampespace or within a class (inside a namespace). It's up to you, there's no right or wrong approach. Personally, I'd put them into a class because that's how I'm doing it in C# and it'll help a bit with productivity: I group related functionality in one place (class). It's easier to manage.
But strictly from a programming point of view, there's no difference, your code won't be cleaner/decoupled or more OOP because you've put functions into a class or namespace
A few advantages when using Namespace or Class for static functions.
Namespace and Class Name helps distinguish functions. You can avoid naming conflicts.
DPDate::FirstDayOfMonth() is better than FirstDayOfMonth() when you want to take advantage of auto suggestion of the IDE.
It is really all about cohesion and decoupling.
You must following this rules:
In OOP you MUST ALWAYS use a CLASS
Your method must have a single responsability
Avoid generic helper classes, classes must have a simple and specific responsability
Don't use static methods, use strategy (pass the object throw the param) to call a method, this way you can create a Mock to test your methods.
Avoid private methods, this make dificult to test your classes
Keep this things in mind, and you will gona make a clean code. =)
Answering Eric about item 4: This code it will use static method:
public function myFunction() {
$deviceId = DeviceManger::getDeviceId('computer 1');
// Rest of code using the device id
}
This way i cant mock the return of Device ID, this way i can:
public function myFunction(deviceManger) {
$deviceId = deviceManager->getDeviceId('computer 1');
// Rest of code using the device id
}
The code with mock in test function:
$deviceManager = $this->getMock('DeviceManager');
$deviceManager->method('getDeviceId')->returnValue(1);
myFuncion($deviceManager);
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 just want to tell you that I am newbie to OOP and it is quite hard to me, but here is my code:
class functions
{
function safe_query($string)
{
$string = mysql_escape_string(htmlspecialchars($string));
return $string;
}
}
class info
{
public $text;
function infos($value)
{
echo functions::safe_query($value);
}
}
Is there any way to make this sentence : echo functions::safe_query($value); prettier? I can use extends, than I could write echo $this->safe_query($value);, but is it a best way? Thank you.
edit: and maybe I even can to not use class functions and just make separate file of functions and include that?
Yes, just define your function outside of a class definition.
function safe_query($string){
return mysql_escape_string(htmlspecialchars($string));
}
Then call it like this
safe_query($string);
Using a functional class is perfectly fine, but it may not the best way to design your application.
For instance, you might have a generic 'string' or 'data' class with static methods like this (implementation missing, obviously):
class strfunc{
public static function truncate($string, $chars);
public static function find_prefix($array);
public static function strip_prefix($string);
public static function to_slug($string); #strtolower + preg_replace
etc.
}
The point of a class like this is to provide you with a collection of generic, algorithmic solutions that you will reuse in different parts of your application. Declaring methods like these as static obviates their functional nature, and means they aren't attached to any particular set of data.
On the other hand, some behaviors, like escaping data for a query, are more specific to a particular set of data. It would probably be more appropriate to write something like this, in that case:
class db_wrapper{
public function __construct($params); #connect to db
public function escape($string);
public function query($sql);
public function get_results();
}
In this case, you can see that all of the methods are related to a database object. You might later use this object as part of another object that needs to access the database.
The essence of OOP is to keep both the data and its relevant behavior (methods) in one place, called an object. Having behavior and data in the same place makes it easier to control data by making sure that the behavior attached to the data is the only behavior allowed to change it (this is called encapsulation).
Further, having the data and behavior in one place means that you can easily pass that object (data and behavior) around to different parts of your application, increasing code reuse. This takes the form of composition and inheritance.
If you're interested in a book, The Object-Oriented Thought Process makes for a decent read. Or you can check out the free Building Skills in Object-Oriented Design from SO's S.Lott. (Tip: PHP syntax is more similar to Java than Python.)
Functions outside a class litter the global namespace, and it's an open invitation to slide back to procedural programming. Since you're moving to the OOP mindset, functions::safe_query($value); is definitely prettier (and cleaner) than a function declared outside a class. refrain from using define() too. but having a functions class that's a mix of unrelated methods isn't the best approach either.
Is there any way to make this sentence
: echo functions::safe_query($value);
prettier?
Not really. IMO having a functions class serves no purpose, simply make it a global function (if it's not part of a more logical class, such as Database) so you can do safe_query($value); instead.
and maybe I even can to not use class
functions and just make separate file
of functions and include that?
Create files for logical blocks of code, not for what type of code it is. Don't create a file for "functions", create a file for "database related code".
Starting with OOP can be a real challenge. One of the things I did was looking at how things were done in the Zend Framework. Not only read the manual (http://www.framework.zend.com/manual/en/zend.filter.input.html, but also look at the source code. It will take some effort but it pays of.
Looking at the context of your question and the code example you posted, I would advice you to look at some basic patterns, including a simple form of MVC, and the principles they are based upon.
I was trying to use array_walk_recursive for something, and wanted to use one of the class' methods as the call back, so trying:
array_walk_recursive($TAINTED, "$this->encode()");
and variations thereof all failed. I eventually settled for:
array_walk_recursive($TAINTED, 'className::encode');
which works, but I've read on here that calling class methods in a static fashion like this is often considered poor practice. Or is this one of those situations where it's necessary?
So, is this the right way to go about it, or is there a way to put in the callback function without having to fall back on using it as a static class method?
array_walk_recursive($TAINTED, array($this, 'encode'));
I know this thread is older but by reading your words "calling class methods in a static fashion like this is often considered poor practice" I have to say that static functions are a good practice when used for the right task. Frameworks like Laravel and Symphony shows the true potential of static methods.
Anyways when you aren't afraid of using static methods you can call your method using self instead of specifying the class name that might change during development process.
array_walk_recursive($TAINTED, 'self::encode');