How to make PHP code like this? - php

$this->admin_model->list_user()
I am writing most of the time my programs in OOP PHP. but I am writing like this...
$this->hello_world().
The above code is CodeIgniter and I think CakePHP also following same coding style.
Please give me simple example how to make my "hello_world" like
$this->something->hello_world().
Thanks you on advance.
Surya

Its nothing special; $this->admin_model is a property which contains an object, and for all purposes is identical to $object->method();
A step by step would look like:
$this->property = new MyObjectWIthADoItMethod();
$this->property->DoIt();

something is just an object of a type which has hello_world() method.
So:
class Something
{
public function hello_world()
{
echo 'Hello, big world!';
// Do work.
}
}
class Program
{
private $something;
public function Run()
{
$this->something = new Something();
$this->something->hello_world()
}
}
$program = new Program();
$program->Run();

Related

How to create sub-variables in PHP class

I started using OOP in PHP for first time, and I dont know how to achieve the following structure for my variables:
$this->myData->generalData->title;
$this->myData->generalData->description;
$this->myData->amount;
$this->myData->addNewData();
Up till now, what I am achieving is a normal variable inside a class:
$this->variablename
I tried doing this code, but it's not working at all:
$this->CDNE = "CDNE";
$this->CDNE->FOLDER = "hello man";
Can you explain me, how all this works?
Just to ilustrate my comment. Doing it with sub-objects could be something like this (a very basic example without attributes initialization):
class GeneralData{
public $title;
public $description;
}
class MyData{
public $generalData;
public $amount;
function __construct(){
$this->generalData = new GeneralData();
}
function addNewData(){
}
}
class MainClass{
public $myData;
function __construct(){
$this->myData = new MyData();
}
}

Method Chaining and Class Inheritance

I think I have more or less managed to get a grasp on OOP/Inheritance, and the basics of method chaining I think I understood as well. However I am still confused about how to actually use some of it.
I wanted to do something that I've seen when working with Magento before:
In Magento, I've seen some sort of "selector-function" used in method chaining. It's a little hard to put into words, but it was something along the lines of:
$categoryName = Mage::getModel('catalog/category')->load($categoryId)->getName();
It's the load($categoryId) part that interests me, as in, a function that selects some instance of something and allows me to run a function on that specific instance.
Now, I am writing a module that allows me to configure certain promotions on our website. Seeing as we'll have many different promotions and I want them to be easily configurable and modifiable, I wanted to do something similar.
So, if I wanted to be able to do something like this:
$prm = new Promotion();
$prm->addPromo('xmasPromo');
$prm->addPromo('nyPromo');
$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');
$prm->getPromo('nyPromo')->setName('Promotion for New Years!');
echo $prm->getPromo('xmasPromo')->getName(); // returns: Promotion for Xmas!
echo $prm->getPromo('nyPromo')->getName(); // returns: Promotion for New Years!
How would the class definition for that have to look like?
This may be much more simple or much more complicated than I anticipate. In either case, thanks a lot!
Edit:
So I did some testing around with the info deceze gave me, but I'm still confused.
Bad naming and putting 2 classes in 1 file aside, here's what I did:
class file:
class Promotion {
private $__arr = array();
public function addPromo($name) {
$this->__arr[$name] = new Promo();
}
public function getPromo($name) {
$this->__arr[$name];
}
}
class Promo {
private $name;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $name;
}
}
and the run file:
require_once 'class.php';
error_reporting(E_ALL);
$prm = new Promotion();
$prm->addPromo('xmasPromo');
$prm->addPromo('nyPromo');
$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');
$prm->getPromo('nyPromo')->setName('Promotion for New Years!');
echo 'X: '.$prm->getPromo('xmasPromo')->getName(); // returns: Promotion for Xmas!
echo "\n";
echo 'N: '.$prm->getPromo('nyPromo')->getName(); // returns: Promotion for New Years!
This gives me Fatal error: Call to a member function setName() on a non-object in /var/www/test/index.php on line 11.
But why? Shouldn't getPromo() give me back the object?
Thanks again..
Thanks to the great guys here, it works now. In case anyone were to pass by here with the same or a similar question, here's the final, working code:
Classes:
class Promotion {
private $__arr = array();
public function addPromo($name) {
$this->__arr[$name] = new Promo();
}
public function getPromo($name) {
return $this->__arr[$name];
}
}
class Promo {
private $name;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
Test file:
require_once 'class.php';
error_reporting(E_ALL);
$prm = new Promotion();
$prm->addPromo('xmasPromo');
$prm->addPromo('nyPromo');
$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');
$prm->getPromo('nyPromo')->setName('Promotion for New Years!');
echo 'X: '.$prm->getPromo('xmasPromo')->getName(); // returns: Promotion for Xmas!
echo "\n";
echo 'N: '.$prm->getPromo('nyPromo')->getName(); // returns: Promotion for New Years!
Method chaining is really simple, all it does is use one particular element of PHP's syntax:
When a function returns an object, you can directly continue with -> after that function.
The longhand version can be:
$bar = $foo->bar();
$baz = $bar->baz();
echo $baz;
$foo->bar() returns an object ($bar) which has a method baz(), and that method returns some value ($baz). This can be written in shorthand like so:
echo $foo->bar()->baz();
$foo->bar() still returns an object which has a method baz(), so you can directly call it without assigning it to an intermediate variable. Maybe this makes it more obvious:
echo ( $foo->bar() )->baz();
You're calling the baz() method on whatever $foo->bar() returns.
$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');
As such, in your above case, all you need to do is to return an object which has the method setName from getPromo. I would assume getPromo is supposed to return some object of, say, the Promo class. If the Promo class has a method setName, you're all set.
If you want to chain methods you just need to always return the object like this
class Chain {
public function firstChain() {
//do something
return $this;
}
public function secondChain() {
//do some stuff
return $this;
}
}
Than when you have an instance of the class you do like this:
$obj = new Chain();
$obj->fistChain()->secondChain();

Modify Variable within Method with Service

I want to know the right way to handle this scenario: modify a variable within a method with a service. I know you could just do:
$input = $this->modify($input)
But that doesn't feel like the correct OOP way of handling the situation. Please see the inline comments.
class myClass {
public function __construct(Service $service)
{
$this->service = $service;
}
public function work($input)
{
// $input = SOMETHING
$this->service->modify($input);
// $input = SOMETHING MODIFIED
Entity::create($input);
}
}
It can be achieved by passing in the input as reference:
public function modify(&$input) {
// ^ See what I did there?
A better approach would be to return the modified input, and assign it again:
$input = $this->service->modify($input);
Don't start messing with references until you know exactly what you're doing.

How to create global function in opencart

I'm trying to create simple function that can be executed on any page.
function something() {
$string = 'Hello World';
return $string;
}
Let's say I'm in the category page, I would just call $a = something(); and it would return my value
Platform : OpenCart
P.S. I'm still studying MVC architecture
Since you are wanting to understand and learn about the MVC system, the correct way to go about this would be to create your own helper file and put it in /system/helper/ and then add the helper to system/startup.php. Take a look at how the json.php / utf8.php are done in these as a guide
Create a new file to system/library/yourclassname.php with same code.
Also please add a class name to your function as below:
class yourclassname {
function something() {
$string = 'Hello World';
return $string;
}
}
And add it to your index.php file as below;
$registry->set('yourclassname', new yourclassname($registry));
Finally add it to your startup.php file as below:
require_once(DIR_SYSTEM . 'library/yourclassname.php');
You can use it anywhere with $this->yourclassname->something();
Thats All..
You can create a function in any opencart library (system/library/)
As example in system/library/document.php
function something() {
$string = 'Hello World';
return $string;
}
And use anywhere in openсart as
$something=$this->document->something();
P/s code in header.tpl will not work in ajax or direct request
Matricore's answer worked perfectly for me, but I also had to construct the new class with the config and db available.
Code below:
class yourclassname {
public function __construct($registry) {
$this->config = $registry->get('config');
$this->db = $registry->get('db');
}
}
You can then run queries via $this->db->query("Your query here");

calling a method of an object at instance creation

In PHP why can't I do:
class C
{
function foo() {}
}
new C()->foo();
but I must do:
$v = new C();
$v->foo();
In all languages I can do that...
Starting from PHP 5.4 you can do
(new Foo)->bar();
Before that, it's not possible. See
One of many question asking the same on SO
Discussion on PHP Internals
Another Discussion on PHP Internals
Relevant Feature Request in BugTracker
But you have some some alternatives
Incredibly ugly solution I cannot explain:
end($_ = array(new C))->foo();
Pointless Serialize/Unserialize just to be able to chain
unserialize(serialize(new C))->foo();
Equally pointless approach using Reflection
call_user_func(array(new ReflectionClass('Utils'), 'C'))->foo();
Somewhat more sane approach using Functions as a Factory:
// global function
function Factory($klass) { return new $klass; }
Factory('C')->foo()
// Lambda PHP < 5.3
$Factory = create_function('$klass', 'return new $klass;');
$Factory('C')->foo();
// Lambda PHP > 5.3
$Factory = function($klass) { return new $klass };
$Factory('C')->foo();
Most sane approach using Factory Method Pattern Solution:
class C { public static function create() { return new C; } }
C::create()->foo();
From PHP 5.4 you CAN do: (new Foo())->someMethod();
In PHP, you can't call an arbitrary method on a freshly created object like new Foo()->someMethod();
Sorry, but that's the way it is.
But you could build a work around like this:
<?php
class CustomConstructor
{
public static function customConstruct($methodName)
{
$obj = new static; //only available in PHP 5.3 or later
call_user_method($methodName, $obj);
return $obj;
}
}
Extend CustomContructor like this:
class YourClass extends CustomConstructor
{
public function someCoolMethod()
{
//cool stuff
}
}
And instantiate them like this:
$foo = YourClass::customConstruct('someCoolMethod');
I have not tested it but this or something like it should work.
Correction: This will only work in PHP 5.3 and later since late static binding is required.
You should not be able to execute code like
new C()->foo();
in other languages, at least not as long as that language accurately follows logic. The object is not just created using C(), but with the full new C(). Therefore, you should hypothetically be able to execute that code if you include another pair of parentheses:
(new C())->foo();
(Be warned: I haven't tested the above, I'm just saying it should hypothetically work.)
Most languages (that I've encountered) deal with this situation the same way. C, C#, Java, Delphi...
I tried this and was successful -
<?php
$obj = new test("testFunc");
class test{
function __construct($funcName){
if(method_exists($this, $funcName)){
self::$funcName();
}
}
function testFunc(){
echo "blah";
return $this;
}
}
?>

Categories