I have wrote this code by looking at similar code from a PHP cookbook. I have few troubles with executing and understanding it + it is not working well. Hope someone can help me.
<?php
class example {
//protected $a;
//protected $c;
public function NumberInput($number){
$this->a = $number;
}
public function NumberOutput(){
return $this->a;
}
}
class example2 {
public function __construct(){
$this->mergingclass = new example;
}
public function numberInput2($number){
$this->c = $number;
}
public function NumberOutput2(){
return $this->c;
}
public function __call($method,$arguments){
echo "called methos is $method <br> ";
;
return $this->x = $arguments;
}
}
$b = new example2;
$b->NumberInput(7);
echo $b->NumberOutput();
?>
so my questions are:
Why do I even need __construct function ? Code is working excatly the same with or without it. Or atleast I can't spot the difference with my newbie abilities. If I understand correctly it should agreggate objects but when I put it in comments nothing changes.
When I execute this code insted of number 7 I get "Array". I suppose number 7 is inside of that array, so how can I echo it ?
Thanks in advance.
First of all, __construct is like a magic method in PHP, that makes it possible to create an object out of class. Each time you write something like this:$myObject = new Object(); constructor of Object class is called by default and it creates object referenced by $myObject variable. So without that method in it, you will not be able to properly use classes and create objects.
use print_r($array) or var_dump($array) to see array structure
Related
Let's say I have this class.
class foo{
function a(){
return $this;
}
}
And I instantiate it as:
$O = new foo();
$O->a()
->a()
->a();
Is there any way to know, in that last function ->a() how many times it was called before?
So, I could output like 'method ->a() has been called twice before this.'
I would like to find out this, without using increment values like declaring a property and then increment it increment it, everytime it is called in a function.
I am just hopping if there is a hidden feature in OOP that can provide for this solution
You can use a static variable inside the method:
class foo{
function a(){
// $count will be initialized the first time a() was called
static $count = 0;
// counter will be incremented each time the method gets called
$count ++;
echo __METHOD__ . " was called $count times\n";
return $this;
}
}
Note that static has a different meaning when used inside a method or function and it has nothing to do with static class members - although it is the same keyword. It means that the variable will be created and initialized only once when the method has been called for the first time.
However, in the example above there is no way to reinitialize that counter. If you want to do that you may introduce a parameter or something like this. Also you may not use a static variable but an object property.. There are tousand ways to do it, tell me your exact application needs I may give a more specific example....
In comments it was suggested to use a decorator for this job. I like this idea and will give a simple example:
class FooDecorator
{
protected $foo;
protected $numberOfCalls;
public function __construct($foo) {
$this->foo = $foo;
$this->reset();
}
public function a() {
$this->numberOfCalls++;
$this->foo->a();
return $this;
}
public function resetCounter() {
$this->numberOfCalls = 0;
}
public function getNumberOfCalls() {
return $this->numberOfCalls;
}
}
Usage example:
$foo = new FooDecorator(new foo());
$foo->a()
->a()
->a();
echo "a() was called " . $foo->getNumberOfCalls() . " times\n";
I know it isn't actually the reverse engineering
I have this function:
<?=$this->get('translator')->trans('dashboard.actions', array(), 'front');?>
I want to understand how to insert a function (using include maybe) that gets called when using that code.
I know the function name needs to be trans, and it has 3 arguments, but how to define it? Let me put this in a more easy way: In a php script how do I print Hello world when using $this->get('translator')->trans('dashboard.actions', array(), 'front');
It's just a regular class method:
class Traslator{
public function trans($a, $b, $c){
return 'Hello world';
}
}
Now, you only need another class method called get() that returns an instance of the previous class:
class Foo{
public function get(){
return new Traslator;
}
}
Full code:
<?php
class Traslator{
public function trans($a, $b, $c){
return 'Hello world';
}
}
class Foo{
public function get(){
return new Traslator;
}
public function test(){
?>
<?=$this->get('translator')->trans('dashboard.actions', array(), 'front');?>
<?php
}
}
$f = new Foo;
$f->test();
$this references the current object instance, and that variable may not be re-assigned. Meaning, to trick PHP into doing what you want requires to add code before and after the line you mention.
By creating a single class, the result can be obtained.
Before the <?=... line
<?php
class C {
function get($s) {
return $this;
}
function trans($s, $a, $f) {
return 'Hello world';
}
function hw() {
?>
Then the line
<?=$this->get('translator')->trans('dashboard.actions', array(), 'front');?>
Then need, to end the class, and call the method that does what you want
<?php
}}
$i = new C();
$i->hw();
Put the 3 blocks of code into a file and call PHP on it, the <?=... line should show "Hello world".
$this->get('translator') return instance of class lets call it "Translator" - on that instance you call trans() method
so you would like to change instance of "Translator" to your extended version
class ExtTranslator extends Translator{
public function trans($params){
echo 'fdsfds'; // here you could add what you like
return parent::trans($params);
}
}
and yes - it's hard to help you cause I don't really know what are you trying to do - to work with that code you must first understand it...
I have a class that generates data based on a few things. I would like to format that data from the outside. So I am trying to pass a function into the class so that it would format that data. I have looked at many examples, but it seems this is unique.
Can anybody give an idea of how to do this? The following code gives an error.
<?php
class someClass {
var $outsideFunc; // placeholder for function to be defined from outside
var $somevar='Me'; // generated text
function echoarg($abc){
$outsideFunc=$this->outsideFunc; // bring the outside function in
call_user_func($outsideFunc,$abc); // execute outside function on text
echo $abc;
}
}
function outsidefunc($param){ // define custom function
$param='I am '.$param;
}
$someClass=new someClass();
$someClass -> outsideFunc = 'outsideFunc'; // send custom function into Class
$someClass -> echoarg($someClass->somevar);
$someClass -> outsidefunc = 'outsidefunc';
In PHP, function names are not case sensitive, yet object property names are. You need $someClass->outsideFunc, not $someClass->outsidefunc.
Note that good OOP design practice calls for the use of getter and setter methods rather than just accessing properties directly from outside code. Also note that PHP 5.3 introduced support for anonymous functions.
Yeah. You are right. Now there is no error. But it does not work either.
By default, PHP does not pass arguments by reference; outsidefunc() does not actually do anything useful. If you want it to set $param in the caller to something else, and do not want to just return the new value, you could change the function signature to look like this:
function outsidefunc(&$param) {
You would also need to change the way you call the function, as call_user_func() does not allow you to pass arguments by reference. Either of these ways should work:
$outsideFunc($abc);
call_user_func_array($outsideFunc, array(&$abc));
Why not pass your function as an argument?
<?php
class someClass {
public $somevar="Me";
public function echoarg($abc,$cb=null) {
if( $cb) $cb($abc);
echo $abc;
}
}
$someClass = new someClass();
$someClass->echoarg($someClass->somevar,function(&$a) {$a = "I am ".$a;});
i am not sure what exactly you are looking for, but what i get is, you want to pass object in a function which can be acheive by
Type Hinting in PHP.
class MyClass {
public $var = 'Hello World';
}
function myFunction(MyClass $foo) {
echo $foo->var;
}
$myclass = new MyClass;
myFunction($myclass);
OP, perhaps closures are what you're looking for?
It doesn't do EXACTLY what you're looking for (actually add function to class), but can be added to a class variable and executed like any normal anonymous function.
$myClass->addFunc(function($arg) { return 'test: ' . $arg });
$myClass->execFunc(0);
class myClass {
protected $funcs;
public function addFunc(closure $func) {
$this->funcs[] = $func;
}
public function execFunc($index) { $this->funcs[$index](); } // obviously, do some checking here first.
}
I'm trying to create some classes and i would like to use this syntax:
$my = new My();
$my->field()->test('test');
I know how to do a $my->test('test'), it's easy - but I don't know how to add a field() attribute to make an easier comprehension of my class in my code.
I can guess it's something like a class into another class - extends - but i'm not sure about that so if you know how to do something similar.
I precise it's only for a better comprehension into my class. I mean the aim is to categorize functions in this My class.
Thank you :)
If you break your php down a bit, you will understand what is going on. For example lets make this:
$my->field()->test('test');
into this (for clarification).
$newObject = $my->field();
$newObject->test('test');
From here you can observe that the return of the method $my->field() is actually an object with another method test which you can then call. It is called method chaining and can be useful at times.
Here is a test case:
class a{
public function My(){
return new b;
}
}
class b{
public function foo(){
echo 'hello bar';
}
}
$a = new a();
$a->My()->foo();
In order to carry out an action on a method the method needs to return an object.
class a {
public function b($c){
echo $c;
return $this;
}
}
would allow
$d = new a();
$d->b("foo")->b("bar");
$d->b("foo")->b("bar")->b("far")->b("tar");
I can't quite understand why the output of this code is '1'.
My guess is that php is not behaving like most other OO languages that I'm used to, in that the arrays that php uses must not be objects. Changing the array that is returned by the class does not change the array within the class. How would I get the class to return an array which I can edit (and has the same address as the one within the class)?
<?php
class Test
{
public $arr;
public function __construct()
{
$this->arr = array();
}
public function addToArr($i)
{
$this->arr[] = $i;
}
public function getArr()
{
return $this->arr;
}
}
$t = new Test();
$data = 5;
$t->addToArr($data);
$tobj_arr = $t->getArr();
unset($tobj_arr[0]);
$tobj_arr_fresh = $t->getArr();
echo count($tobj_arr_fresh);
?>
EDIT: I expected the output to be 0
You have to return the array by reference. That way, php returns a reference to the array, in stead of a copy.
<?php
class Test
{
public $arr;
public function __construct()
{
$this->arr = array();
}
public function addToArr($i)
{
$this->arr[] = $i;
}
public function & getArr() //Returning by reference here
{
return $this->arr;
}
}
$t = new Test();
$data = 5;
$t->addToArr($data);
$tobj_arr = &$t->getArr(); //Reference binding here
unset($tobj_arr[0]);
$tobj_arr_fresh = $t->getArr();
echo count($tobj_arr_fresh);
?>
This returns 0.
From the returning references subpage:
Unlike parameter passing, here you have to use & in both places - to
indicate that you want to return by reference, not a copy, and to
indicate that reference binding, rather than usual assignment, should
be done
Note that although this gets the job done, question is if it is a good practice. By changing class members outside of the class itself, it can become very difficult to track the application.
Because array are passed by "copy on write" by default, getArr() should return by reference:
public function &getArr()
{
return $this->arr;
}
[snip]
$tobj_arr = &$t->getArr();
For arrays that are object, use ArrayObject. Extending ArrayObject is probably better in your case.
When you unset($tobj_arr[0]); you are passing the return value of the function call, and not the actual property of the object.
When you call the function again, you get a fresh copy of the object's property which has yet to be modified since you added 5 to it.
Since the property itself is public, try changing:
unset($tobj_arr[0]);
To: unset($t->arr[0]);
And see if that gives you the result you are looking for.
You are getting "1" because you are asking PHP how many elements are in the array by using count. Remove count and use print_r($tobj_arr_fresh)