Method chaining - php

class A {
public function model($name) {
if (file_exists($name.'.php')) {
require $name.'.php';
$this->$name = new $name();
}
}
}
class C extends A {
function __construct() {
$this->load = $this;
$this->load->model('test');
$this->test->say();
}
}
$Controller = new C();
I want to create a simple code igniter like loader class. Is there a proper way for doing this technique?

You would use Fluent Interface pattern.
<?php
class Employee
{
public $name;
public $surName;
public $salary;
public function setName($name)
{
$this->name = $name;
return $this;
}
public function setSurname($surname)
{
$this->surName = $surname;
return $this;
}
public function setSalary($salary)
{
$this->salary = $salary;
return $this;
}
public function __toString()
{
$employeeInfo = 'Name: ' . $this->name . PHP_EOL;
$employeeInfo .= 'Surname: ' . $this->surName . PHP_EOL;
$employeeInfo .= 'Salary: ' . $this->salary . PHP_EOL;
return $employeeInfo;
}
}
# Create a new instance of the Employee class:
$employee = new Employee();
# Employee Tom Smith has a salary of 100:
echo $employee->setName('Tom')
->setSurname('Smith')
->setSalary('100');
# Display:
# Name: Tom
# Surname: Smith
# Salary: 100

Related

Property of a PHP Object itself is another Object of another class

I am pretty sure that we can store reference to an Object's property with an Object of a different class.
But I am stuck with this code.
The __construct() functions of both metro and town assigns the values for $name and $pop of those objects . But I need the __construct() function of the class city to create a new object of either class metro or class town depending on the value of $pop of the object of class city
<?php
class metro
{
public $name;
public $pop;
function __construct($name,$pop)
{
$this->name = $name;
$this->pop = $pop;
}
}
class town
{
public $name;
public $pop;
function __construct($name,$pop)
{
$this->name = $name;
$this->pop = $pop;
}
}
class city
{
public $name;
public $pop;
public $derived_city;
function __construct($name,$pop)
{
$this->name = $name;
$this->pop = $pop;
if ($this->pop >= 50)
{
$derived_city = new metro($this->name,$this->pop);
}
else
{
$derived_city = new town($this->name,$this->pop);
}
}
}
$city1 = new city("Bombay",100);
echo $city1->derived_city->pop;
?>
Do this:
class metro
{
public $name;
public $pop;
function __construct($name,$pop)
{
$this->name = $name;
$this->pop = $pop;
}
}
class town
{
public $name;
public $pop;
function __construct($name,$pop)
{
$this->name = $name;
$this->pop = $pop;
}
}
class city
{
public $name;
public $pop;
public $derived_city;
function __construct($name,$pop)
{
$this->name = $name;
$this->pop = $pop;
if ($this->pop >= 50)
{
$derived_city = new metro($this->name,$this->pop);
}
else
{
$derived_city = new town($this->name,$this->pop);
}
$this->derived_city = $derived_city;
}
}
$city1 = new city("Bombay",100);
print_r($city1->derived_city);
echo $city1->derived_city->pop;

Is it possible to chain static together with non-static method in PHP?

Here is my sample code Class User but not working when I added the static method with the public methods:
<?php
namespace App\Classic;
class User
{
public $username;
public static $upassword;
public $age;
public $message;
public function username($username)
{
$this->username = $username;
echo $this->username."<br>";
return $this;
}
public static function password($upassword)
{
self::$upassword = $upassword;
echo self::$upassword."<br>";
}
public function age($age)
{
$this->age = $age;
echo $this->age."<br>";
return $this;
}
public function message($message)
{
$this->message = $message;
echo $this->message."<br>";
return $this;
}
}
and this is the side effect of chaining method:
$user = new User();
$user::password('secret')
->username('admin')
->age(40)
->message('lorem ipsum');
I dont know what is the logic behind doing this, but still this solution will be helpful.
Try this code snippet here
<?php
namespace App\Classic;
ini_set('display_errors', 1);
class User
{
public $username;
public static $upassword;
public static $currentObject=null;//added this variable which hold current class object
public $age;
public $message;
public function __construct()//added a constructor which set's current class object in a static variable
{
self::$currentObject= $this;
}
public function username($username)
{
$this->username = $username;
echo $this->username . "<br>";
return $this;//added this statment which will return current class object
}
public static function password($upassword)
{
self::$upassword = $upassword;
echo self::$upassword . "<br>";
return self::$currentObject;
}
public function age($age)
{
$this->age = $age;
echo $this->age . "<br>";
return $this;
}
public function message($message)
{
$this->message = $message;
echo $this->message . "<br>";
return $this;
}
}
$user = new User();
$user::password('secret')
->username('admin')
->age(40)
->message('lorem ipsum');

Managing collection of items through adding/removing

I want have an in-memory data structure to be able to add or remove an item (in this instance a student) into some sort of table (just like a shopping cart) from the collection class I have created. At the moment, it just displays students. For instance, if I click add student, it will pop up below, and I can delete this student from below also.
How I could implement this?
Here is my Member.php class
<?php
class Member {
private $name;
private $age;
private $gender;
private $course;
public function __construct($name,$age, $gender, $course){
$this->name = $name;
$this->age = $age;
$this->gender = $gender;
$this->course = $course;
}
public function setName($name) { //Sets the age value
$this->name = $name;
}
public function setAge($age) { //Sets the age value
$this->age = $age;
}
public function setGender($gender) { //Sets the gender value
$this->gender = $gender;
}
public function setCourse ($course) {
$this->course = $course;
}
public function getName() { //Gets the name value
return $this->name;
}
public function getAge() { //Gets the age value
return $this->age;
}
public function getGender() { //Gets the gender value
return $this->gender;
}
public function getCourse() {
return $this->course;
}
}
?>
Here is my ObjectCollection.php
<?php
class ObjectCollection
{
//This is an array to hold line items
private $items_array ;
private $itemCounter; //Count the number of items
public function __construct() {
//Create an array object to hold line items
$this->items_array = array();
$this->itemCounter=0;
}
public function getItemCount(){
return $this->itemCounter;
}
public function addItem($item) {
$this->itemCounter++;
$this->items_array[] = $item;
}
public function getItem($index) {
return $this->items_array[$index];
}
}
?>
And finally displaying this through testcollection.php
<?php
$ObjColl = new ObjectCollection();
$member1 = new Member("Jessica Davidson", 21, "Female", "Computing");
$ObjColl->addItem($member1);
$member2 = new Member("Lucy Barnes", 22, "Female", "History");
$ObjColl->addItem($member2);
$member3 = new Member("Mark Smith", 24, "Male", "Social Science");
$ObjColl->addItem($member3);
for($i = 0;$i < $ObjColl->getItemCount();$i++){
$item = $ObjColl->getItem($i);
if ($item instanceof Member) {
print "<br> University Member: ";
}
print "Name: " . $item->getName();
print ". Age: " . $item->getAge();
print ". Gender: " . $item->getGender();
print ". Enrolled on: " .$item->getCourse() . " course<br>";
}
?>
At first if your ObjectCollection must collect only objects of Member class, use parameter type declaration. It’s good practice in OOP.
public function addItem(Member $item)
At second if you want work with ObjectCollection like with array, implement ArrayAccess and Iterator interfaces.
Example
<?php
class Member{
private $__name;
public function __construct($name){
$this->__name = $name;
}
public function getName(){
return $this->__name;
}
}
class MemberCollection implements ArrayAccess, Iterator{
private $__Collection = [];
private $__position = 0;
public function __construct(){
}
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->__Collection[] = $value;
} else {
$this->__Collection[$offset] = $value;
}
}
public function offsetExists($offset) {
return isset($this->__Collection[$offset]);
}
public function offsetUnset($offset) {
unset($this->__Collection[$offset]);
}
public function offsetGet($offset) {
return isset($this->__Collection[$offset]) ? $this->__Collection[$offset] : null;
}
function rewind() {
$this->__position = 0;
}
function current() {
return $this->__Collection[$this->__position];
}
function key() {
return $this->__position;
}
function next() {
++$this->__position;
}
function valid() {
return isset($this->__Collection[$this->__position]);
}
public function addItem(Member $Member){
$this->offsetSet(null, $Member);
}
}
$MC = new MemberCollection();
$Member1 = new Member('Name 1');
$Member2 = new Member('Name 2');
$MC->addItem($Member1);
$MC->addItem($Member2);
foreach ($MC as $Member){
echo '<br>' . $MC->key() . ':<br>';
var_dump($Member->getName());
}
unset($MC[0]); //Delete member from collection
?>

PHP access methods from parent class

Hello guys I'm new to PHP's OOP so I need a little help from my test scripts.
This is what I've tried so far:
index.php
<?php
include("shared.php");
?>
<!DOCTYPE html>
<html>
<head>
<title>Car Details</title>
</head>
<body>
<?php
$car1 = new Car("Audi");
echo $car1->showCarDetails();
?>
</body>
</html>
car.php
<?php
class Car extends CarDetails {
public $name;
public $color = "Freaking Sexy White";
public $price = "PHP 4,000,000.00";
public function _construct($name) {
$this->setName($name);
$this->getColor();
$this->getPrice();
}
public function setName($name) {
$this->name = $name;
}
public function setColor($color) {
$this->color = $color;
}
public function setPrice($price) {
$this->price = $price;
}
public function getName() {
return $this->name;
}
public function getColor() {
return $this->color;
}
public function getPrice() {
return $this->price;
}
public function showCarDetails() {
print nl2br("I have an awesome car. Below are the details :)\r\n".
"Brand: " . $this->getName() . "\r\n" .
"Model: " . parent::getModel(). "\r\n" .
"Color: " . $this->getColor() . "\r\n" .
"Price: " . $this->getPrice()
);
}
}
?>
cardetails.php
<?php
class CarDetails {
public $model = "A7 Sportback";
public $engine = "FSI technology";
public function setModel($model) {
$this->model = $model;
}
public function getModel() {
return $this->model;
}
public function setEngine($engine) {
$this->engine;
}
public function getEngine() {
return $this->getEngine;
}
}
?>
shared.php
<?php
function __autoload($className)
{
//echo "We are requesting the " . $className . " class";
if(file_exists($className . ".php"))
{
require_once($className . ".php");
//echo "The " . $className . " has been included";
}
}
?>
I want to access the method from my parent class which is CarDetails.php, getModel() and getEngine(). But I don't know how to do that, and also what I have declared in the constructor of Car.php in my index.php is not found.
The output:
Notice: Object of class Car could not be converted to int in C:\xampp\htdocs\oop\cardetails.php on line 13
I have an awesome car. Below are the details :)
Brand:
Model: 1
Color: Freaking Sexy White
Price: PHP 4,000,000.00
But my intended output should be:
I have an awesome car. Below are the details :)
Brand: Audi
Model: A7 Sportback
Color: Freaking Sexy White
Price: PHP 4,000,000.00
What is the problem in my code? Any ideas? I'd truly appreciate your help. Thanks.
UPDATE:
I can now access the methods from my parent class. But the problem is, I'm not seeing anything that I declared in my constructor.
Brand: __
Where it should be:
Brand: Audi
Since I passed in "Audi" in index.php
You have a couple of typos in cardetails.php:
public function setEngine($engine) {
$this->engine;
}
public function getEngine() {
return $this->getEngine;
}
should instead be
public function setEngine($engine) {
$this->engine = $engine;
}
public function getEngine() {
return $this->engine;
}
Also, in car.php:
public function _construct($name) {
should be
public function __construct($name) {
I believe that's causing the weirdness you're seeing.
So I've made a few changes here, the whole point behind extending your class is so that your child class HAS the public/protected functionality that the parent class had.
This would mean that your child class Car shouldn't need to call parents when accessing the getModel or any other functions.
You can see the code changes run live here, https://ideone.com/vCfxYQ
<?php
class Car extends CarDetails {
public $name;
public $color = "Freaking Sexy White";
public $price = "PHP 4,000,000.00";
public function __construct($name) {
$this->setName($name);
$this->getColor();
$this->getPrice();
}
public function setName($name) {
$this->name = $name;
}
public function setColor($color) {
$this->color = $color;
}
public function setPrice($price) {
$this->price = $price;
}
public function getName() {
return $this->name;
}
public function getColor() {
return $this->color;
}
public function getPrice() {
return $this->price;
}
public function showCarDetails() {
print nl2br("I have an awesome car. Below are the details :)\r\n".
"Brand: " . $this->getName() . "\r\n" .
"Model: " . $this->getModel(). "\r\n" .
"Color: " . $this->getColor() . "\r\n" .
"Price: " . $this->getPrice()
);
}
}
class CarDetails {
public $model = "A7 Sportback";
public $engine = "FSI technology";
public function __construct() {
}
public function setModel($model) {
$this->model = $model;
}
public function getModel() {
return $this->model;
}
public function setEngine($engine) {
$this->engine = $engine;
}
public function getEngine() {
return $this->getEngine;
}
}
$car1 = new Car("Audi");
echo $car1->showCarDetails();

Is it possible to pass arguments to the class and the parent class constructor?

Class a {
public function __construct($a){
$this->age = $a;
}
}
Class b extends a {
public function printInfo(){
echo 'age: ' . $this->age . "\n";
}
}
$var = new b('age');
$var->printInfo();
I understand how this code works, however is it possible to pass arguments to the constructor of the class and parent class?
My attempt below is causing an error
Class a {
public function __construct($a){
$this->age = $a;
}
}
Class b extends a {
public function __construct($name){
$this->name = $name;
}
public function printInfo(){
echo 'name: ' . $this->name . "\n";
echo 'age: ' . $this->age . "\n";
}
}
$var = new b('name', 'age');
$var->printInfo();
?>
Yes, you simply need to use the parent::__construct() method.
Like so:
class a{
/**
* The age of the user
*
* #var integer
*/
protected $age;
function __construct($a){
$this->age = $a;
}
}
class b extends a{
/**
* The name of the user
*
* #var string
*/
protected $name;
function __construct($name,$age){
// Set the name
$this->name = $name;
// Set the age
parent::__construct($age);
}
public function printInfo(){
echo 'name: ' . $this->name . "\n";
echo 'age: ' . $this->age . "\n";
}
}
$var = new b('name','age');
$var->printInfo();
Just make sure the variables are set to public or protected!
You can pass value to the parent constructor but the way you are doing is wrong,
$var = new b('name', 'age');
it is as if the child class accepts two parameters in its constructor but in real it has only one parameter.
You can pass parameter to parent constructor something like this
parent::__construct($var);
So change you class b to this
Class b extends a {
public function __construct($name, $age){
$this->name = $name;
parent::__construct($age);
}
public function printInfo(){
echo 'name: ' . $this->name . "\n";
echo 'age: ' . $this->age . "\n";
}
}
Yes you can pass the argument to the class as well as parent class
Class a {
public function __construct($age){
$this->age = $a;
}
}
Class b extends a {
public function __construct($name,$age){
parent::__construct($age);
$this->name = $name;
}
}
$var = new b('name', 'age');
?>
Just call parent::__construct in the child. for example
class Form extends Tag
{
function __construct()
{
parent::__construct();
// Called second.
}
}
Here is how is should go:
<?php
class a {
private $age;
public function __construct($age){
$this->age = $age;
}
public function getAge()
{
return $this->age;
}
}
class b extends a {
private $name;
public function __construct($age, $name){
parent::__construct($age);
$this->name = $name;
}
public function printInfo(){
echo 'name: ' . $this->name . "\n";
echo 'age: ' . $this->getAge() . "\n";
}
}
$b = new b(20, "Bob");
$b->printInfo();
?>

Categories