I have a class called adminItems within adminitems.class.php. I am trying to include one of the function of this class in xmlParser::someName() within xmlParser.class.php.
Like this:
require_once("adminitems.class.php");
$obj = new adminitems();
class xmlParser
{
function someName()
{
$obj->addAds(); // addAds is within adminItems object
}
}
`
Is this a correct way of doing it?
Don't use extends simply to gain extra functionality. This is a code smell and implies that xmlParser is-a adminItems which it is obviously not. Also, you can't then extend again in the future because PHP doesn't have multiple inheritance. Choose composition over inheritance like this example shows.
Use Dependency Injection. Invert the control of your objects so that they don't depend on each other: see Inversion on Control.
class xmlParser
{
/**
* #var adminItems
*/
protected $adminItems;
/**
* #constructor
*
* #param adminItems $adminItems
*/
public function __construct(adminItems $adminItems)
{
$this->adminItems = $adminItems;
}
/**
* Whatever this does...
*/
function someName()
{
$this->adminItems->addAds();
}
}
`
You need to, external to the classes you create, wire them together like so. You pass adminItems into the xmlParser, then use it how you need to. This is called Dependency Injection and is something you can do in all object oriented languages, not just php.
You would use the above object API like this:
$adminItems = new adminItems;
$xmlParser = new xmlParser($adminItems);
$xmlParser->somName();
Really simple. Your objects (think of them as re-usable libraries) should not depend on other objects except by constructor or method injection - so you can substitute them out leading to testable and inherently clean code.
Also, I urge you to take a look at the following useful links:
PSR-2 for naming conventions:
Use XmlParser instead of xmlParser for your class names
PSR-4 for autoloading:
Learn how to use composer to generate your autoload files for you
Learn how your files have a 1:1 mapping with directory structure
Learn how you only ever need to use an include once in your project
If a class B need a function of the class A, you have many solutions in PHP:
1. Inheritance
Extend the class A with the class B. The class B will be able to access the public and protected method of the class A.
class B extends A {
}
I wouldn't recommend this. It is a really bad practice in OOP to use inheritance just to use one function of a class that has not the same responsability.
2. Traits
Use traits (since PHP5.4.0):
trait factoredMethods {
function getX() { /*...*/ }
function setY() { /*...*/ }
}
class A {
use factoredMethods;
}
class B {
use factoredMethods;
}
This could be an interesting solution in certain cases but it is often a patch on a bad conception.
3. Composition
The best option is to use composition. B uses A:
class A {
}
class B {
private $a;
public function __construct(A $a) {
$this->a = $a;
}
}
$a = new A();
$b = new B($a);
Of course, the method you want to use in A must be public. I would highly suggest to use an interface between A and B in order to have a low coupling.
Almost the correct method - but $obj is not in scope. An ugly solution would be to delcare it in the global scope...
require_once("adminitems.class.php");
global $obj;
$obj = new adminitems();
class xmlParser
{
function someName()
{
global $obj;
$obj->addAds();
}
You can refine this approach using namespaces but the right answer is probably to pass a reference into scope, e.g.
function someName($obj)
{
$obj->addAds();
}
You can use other class function by extending the parent class
class xmlParser extends adminitems{
function someName(){
$obj->addAds();
}
}
Related
First file:
class Class_one {
public function __construct() {
}
public function show_name() {
echo "My Name is Siam";
}
public function show_class() {
echo "I read in class 7";
}
}
Second file:
<?php
require_once './Class_one.php';
class Class_two {
public $class_one;
public function __construct() {
$aa = new Class_one();
$this->class_one = $aa;
}
public function history() {
$this->class_one->show_name();
}
}
$ab = new Class_two();
$ab->history();
What will happen if i don't instantiate class_one in class_two and extend class_one into class_two? Is there any difference?
There's only one potential gotcha here: Class_two won't have direct access to Class_one private/protected methods and variables. That can be a good thing (encapsulation is where a class does some specific task and you don't want children to interfere with it), but it can also mean you can't get to the data you need.
I would suggest you do Class_two as a dependency injection (as shown in your example), however
class Class_two {
public $class_one;
public function __construct(Class_one $class) {
$this->class_one = $class;
}
}
It should be a semantic difference:
You use inheritance when relationship between two classes can be expressed with to be verb. For example: My Ford is a Car
You use association/composition when relationship between two classes can be expressed with to have verb. For example: My car has an engine.
Above rules should be the first consideration when choosing inheritance or association in object-oriented programming. There've been always discussion about avoiding inheritance, and some will argue that you should choose composition over inheritance. See this other Q&A: Prefer composition over inheritance?
In terms of pure coding, as #Machavity on his answer has already said, there could be accessibility limitations when using composition instead of inheritance, but I wouldn't decide which approach to use based on member accessibility.
I want to disable a class to be instantized by new operator, but lets suppose a getObject method what creates and returns an instance of it. Is it doable?
class C
{
protected function __construct()
{
}
public static function getObject()
{
return new self();
}
}
UPDATE:
The code above fulfills the requirement: the class cannot be instantiated using new, one needs to use the factory method getObject() to create an object. However, the OP did not specify the reason they need such a construct.
There are several reasons such a design emerges; one of them is when the creation of objects of type C needs to be completed with some initialization that, for whatever reason, cannot be done in the class' constructor.
Another reason for this way of constructing objects of class C is the Singleton design pattern; which in fact is an "anti-pattern", but this is another discussion; in order to implement a Singleton, class C should look like this:
class C
{
private static $instance = NULL;
protected function __construct()
{
}
public static function getObject()
{
if (! isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
}
Singleton or not, because method getObject() is static it cannot be stubbed or mocked by the test frameworks and its original implementation have to be used. More, because it is the only way to create objects of class C, other classes that use this class cannot be tested in isolation.
All in all, even the construction is possible, it is not recommended. Enforcing the creation of objects of class C using language mechanisms made the class a nuisance for testing other classes that use it.
If the creation of objects of class C needs to be done by a certain method because of its complex initialization, a better way is use the Builder design pattern. Make it a non-static method of another class (the "builder") and instruct the programmers (using the class documentation) to not create objects of class C directly, using new. This way it does not affect the testability of other classes.
I want to disable a class to be instantized by new operator
A common approach is to privatize the constructor.
class Example {
private function __construct() {
}
}
The following would result in a fatal error.
$object = new Example();
While this will work, I would encourage you, and future readers, to review Design Patterns in PHP.
I am new to PHP and just get into OOP. I have few generic methods used to set and get properties. I use them quite often in almost all the classes, i put those methods in a class and extends other classes from it. Now i can access the methods from child class but dont know how set and get attributes of child class through them ... parent class base.php
class Base
{
public function __construct()
{
}
function __set($propName, $propValue)
{
$this->$propName = $propValue;
}
function setProperties(array $data)
{
foreach($data as $propName => $propValue)
$this->$propName = $propValue;
}
function __get($propName)
{
return (isset($this->$propName))? $this->$propName : "Invalid property!";
}
function getProperties(array $properties)
{
foreach($properties as $propName)
$propVals[$propName] = $this->$propName;
return $propVals;
}
}
child class categories.php
class categories extends Base
{
private $id;
private $pid;
private $title;
private $status;
public function __construct()
{
parent::__construct();
}
}
and i called it like
$objCat = new categories();
$objCat->setProperties(array('id'=>'10', 'pid'=>'6'));
print_r( $objCat->getProperties(array('id', 'pid')));
Need little guidance here. If its the right way? or at least is it possible to do it like this? if so how to accomplish this ...
thanks
Extending a class is something you only want to do when you can say class categories is a class Base. Something like that sort of utility class you have their is almost always the wrong way to go. PHP also has introduced something called traits for copy/paste code. However my personal preference is that it is something you will never want to use, because it tightly couples the traits to your class, which is something you want to avoid.
See for more information the Liskov Substitution principle in SOLID programming.
If it was up to me I would avoid those magic getters / setters either way and just add your own getters / setters methods to the class.
The mistake about some base class isn't something only you are doing (hell even I have done it in the past). Think about some class Database and a class Article. Because the Article class needs access to the database many people let the class extend the Database class. This isn't correct because an article isn't an database. Instead an instance of the database class should be injected into the article class by using dependency injection. The instance should either be injected into the class constructor (if all or many methods need access to it) or just the methods that need it. So when extending a class you have to be able to say class B is a class A.
Some other notes about your code:
Always make your class names PascalCase. This is not really required to make your code work, but it follows a naming convention often used.
And my personal preference a bit: please always add curly braces to your foreach statements. It is more clear what is happening when other people are reading your code.
Can we create an object of a class inside another class in php?I hav made a small application in php,now I am trying to convert the entire code in a class-methods-object fashion.I m now Confused.
You you can do that, but whether you should depends on the lifetime of the two classes and their relation to each other. Basically, you have the choice between Composition and Aggregation.
Composition
You use Composition when the created object has a lifetime equal or less than the object that will use it, e.g.
class A
{
private $belongsToAOnly;
public function __construct()
{
$this->belongsToAOnly = new IBelongToA;
}
}
In this case A "owns" IBelongToA. When A is destroyed, IBelongToA is destroyed too. It cannot live on it's own and is likely just an implementation detail of A. It could be a ValueObject like Money or some other Data Type.
From Craig Larman's "Applying UML and Patterns":
the composite is responsible for creation and deletion of it's parts - either by itself creating/deleting the parts, or by collaborating with other objects. Related to this constraint is that if the composite is destroyed, its parts must be destroyed, or attached to another composite"
Aggregation
You use Aggregation when the lifetime of the created object is longer:
class A
{
private $dbAdapter;
public function __construct(DbAdapter $dbAdapter)
{
$this->dbAdapter = $dbAdapter;
}
}
Unlike with Composition, there is no implication of ownership here. A uses DbAdapter but when A is destroyed DBAdapter lives on. It's a "uses" relationship instead of an "owns" relationship.
Creator Pattern (GRASP)
A good heuristic to decide when an object may create another object at runtime can be found in the Creator Pattern in GRASP which states that objects may create other objects when
Instances of B contains or compositely aggregates instances of A
Instances of B record instances of A
Instances of B closely use instances of A
Instances of B have the initializing information for instances of A and pass it on creation.
Alternatively, you can create Factories whenever you need to create instances of something and aggregate the factory instances, which will give you a cleaner separation of collaborators and creators.
Testability
An issue stemming from creating objects within objects is that they are difficult to test. When you do unit-testing, you usually do not want to recreate and bootstrap the entire system environment but concentrate on testing just that particular class in isolation. To do that, you swap out dependencies of that class with Mock Objects. You cannot do that when you use Composition.
So depending on what the collaborators of a class do, you might want to decide to always use Aggregation, because then you are effectively doing Dependency Injection all the way, which will allow you to swap out collaborators of a class easily, for instance to replace them with Mocks.
Yes you can, but that increases code coupling and makes testing harder.
I'd suggest creating it outside the class and pass it as an argument (it is called Dependency Injection).
class Foo
{
}
class Bar
{
public function __construct(Foo $foo)
{
$this->foo = $foo;
}
}
$foo = new Foo();
$bar = new Bar($foo);
yes you can do it ..
here is one example..
a.php
<?php
class a{
public function function_1(){
echo "b";
}
}
?>
b.php
<?php
include_once ("a.php");
class b{
public function function_b(){
$a = new a;
$a->function_1();
}
}
$b= new b;
$b->function_b();
?>
Yes, you can create an object from a specific class from inside another class.
class SomeClass{
}
class SomeOtherClass {
function hello(){
$o = new SomeClass;
}
}
Yes, you can also define a function in a class. You can do everything in a class in php, please post your code where you confused.
Examples:
Object in a class.
class Foo
{
public $bar; // another object!
public __construct()
{
$this->bar = new Bar();
}
}
(global)Function in a class
<?php
class Foo
{
public function __construct()
{
function __construct()
{
echo "Yes, I'm a global function!";
}
}
}
new Foo();
__construct();
?>
I want create a helper class that containing method like cleanArray, split_char, split_word, etc.
The helper class it self will be used with many class. example :
Class A will user Helper, Class B, Class C, D, E also user Helper Class
what the best way to write and use helper class in PHP ?
what i know is basic knowledge of OOP that in every Class that use Helper class must create a helper object.
$helper = new Helper();
It that right or may be some one can give me best way to do that.
I also will create XXX Class that may use Class A, B, C, etc.
UPDATE : ->FIXED my fault in split_word method :D
Based on Saul, Aram Kocharyan and alex answer, i modified my code, but its dont work, i dont know why.
<?php
class Helper {
static function split_word($text) {
$array = mb_split("\s", preg_replace( "/[^\p{L}|\p{Zs}]/u", " ", $text ));
return $this->clean_array($array);
}
static function split_char($text) {
return preg_split('/(?<!^)(?!$)/u', mb_strtolower(preg_replace( "/[^\p{L}]/u", "", $text )));
}
}
?>
and i use in other Class
<?php
include "Helper.php";
class LanguageDetection {
public function detectLanguage($text) {
$arrayOfChar = Helper::split_char($text);
$words = Helper::split_word($text);
return $arrayOfChar;
}
}
$i = new Detection();
print_r($i->detectLanguage("ab cd UEEef する ح خهعغ فق 12 34 ٢ ٣ .,}{ + _"));
?>
Helper classes are usually a sign of lack of knowledge about the Model's problem domain and considered an AntiPattern (or at least a Code Smell) by many. Move methods where they belong, e.g. on the objects on which properties they operate on, instead of collecting remotely related functions in static classes. Use Inheritance for classes that share the same behavior. Use Composition when objects are behaviorally different but need to share some functionality. Or use Traits.
The static Utils class you will often find in PHP is a code smell. People will throw more or less random functions into a class for organizing them. This is fine when you want to do procedural coding with PHP<5.2. As of 5.3 you would group those into a namespace instead. When you want to do OOP, you want to avoid static methods. You want your objects to have High Cohesion and Low Coupling. Static methods achieve the exact opposite. This will also make your code less testable.
Are Helper Classes Evil?
Killing the Helper class, part two
Functional Decomposition AntiPattern
Is the word "Helper" in a class name a code smell?
Moreover, every Class that use Helper class must create a helper object is a code smell. Your collaborators should not create other collaborators. Move creation of complex object graphs into Factories or Builders instead.
As a rule of thumb, helpers should contain functionality that is common but has no special designation under the overall architecture of the application.
Suffix the classname with Helper
Use static methods whenever possible
In short:
// Helper sample
//
class ConversionHelper {
static function helpThis() {
// code
}
static function helpThat() {
// code
}
}
// Usage sample
//
class User {
function createThings() {
$received = ConversionHelper::helpThis();
}
}
Instead of creating static class , you should just write simple functions , and include that file at the index/bootstrap file (you can even use namespaces with it).
Instead of:
class Helper {
static function split_word($text) { ...
static function split_char($text) { ...
}
It should be:
namespace Helper;
function split_word($text) { ...
function split_char($text) { ...
There is no point wrapping it all up in a class. Just because you put it in a class doesn't make it object oriented .. actually it does the exact oposite.
You could create a class with static methods...
class Str {
public static function split_char($str, $chr) {
...
}
}
You could also namespace a bunch of functions with a namespace, but I think the former is preferred.
Use public static methods in the class as such:
/* Common utility functions mainly for formatting, parsing etc. */
class CrayonUtil {
/* Creates an array of integers based on a given range string of format "int - int"
Eg. range_str('2 - 5'); */
public static function range_str($str) {
preg_match('#(\d+)\s*-\s*(\d+)#', $str, $matches);
if (count($matches) == 3) {
return range($matches[1], $matches[2]);
}
return FALSE;
}
// More here ...
}
Then invoke them like this:
CrayonUtil::range_str('5-6');
If in another file, use the following at the top:
require_once 'the_util_file.php';