I use multiple construct from this site.
I modified it for my needs.
I get fatal errors:
Missing argument 3 for ChildClass::__construct2()
and chained errors...
Missing argument 4 for ChildClass::__construct2()
Missing argument 5 for ChildClass::__construct2()
Undefined variable: c
Undefined variable: d
And both constructors have part of identical code. How can I put it in common __construct.
$arr = array (
"key1" => "val1",
"key2" => "val2"
);
$demo = new Demo("stack", $arr );
class ParentClass {
function __construct($var1 = "1", $var2 = "2"){
// distinctly different code
}
}
class ChildClass extends ParentClass {
function __construct(){
$a = func_get_args();
$i = func_num_args();
if (method_exists($this,$f='__construct'.$i)) {
call_user_func_array(array($this,$f),$a);
}
}
function __construct1( $a, array $e ) {
$this->ex = $a;
$this->ex3 = $e['key1'];
$this->ex4 = $e['key2'];
}
function __construct2( $a, $b, $c, $d, array $e ) {
$this->ex = $a + 1 - $v + $c; //example
$this->ex2 = $d;
$this->ex3 = $e['key1'];
$this->ex4 = $e['key2'];
}
}
And both constructors have part of identical code. How can I put it in common __construct.
thanks.
The number specified after __construct tells how many parameter it will except . You specified 2 after __construct but you are giving it 5 parameters because of which it is giving the error. Change 2 to 5.Also rename __construct1 to __construct2 Use the code below
$arr = array (
"key1" => "val1",
"key2" => "val2"
);
$demo = new Demo("stack", $arr );
class ParentClass {
function __construct($var1 = "1", $var2 = "2"){
// distinctly different code
}
}
class ChildClass extends ParentClass {
function __construct(){
$a = func_get_args();
$i = func_num_args();
if (method_exists($this,$f='__construct'.$i)) {
call_user_func_array(array($this,$f),$a);
}
}
function __construct2( $a, array $e ) {
$this->ex = $a;
$this->setE($e);
}
function __construct5( $a, $b, $c, $d, array $e ) {
$this->ex = $a + 1 - $v + $c; //example
$this->ex2 = $d;
$this->ex3 = $e['key1'];
$this->ex4 = $e['key2'];
}
}
Hope this helps you
It's because the 2 in __construct2 tells it expects 2 parameters, but it expects 5. Change the name to __construct5.
To put the identical code to one place, make it separate method that will be called from both constructors, full code:
class ChildClass extends ParentClass {
function __construct(){
$a = func_get_args();
$i = func_num_args();
if (method_exists($this,$f='__construct'.$i)) {
call_user_func_array(array($this,$f),$a);
}
}
function __construct2( $a, array $e ) { // rename method: 1 => 2
$this->ex = $a;
$this->setE($e);
}
function __construct5( $a, $b, $c, $d, array $e ) { // rename method: 2 => 5
$this->ex = $a + 1 - $v + $c; //example
$this->ex2 = $d;
$this->setE($e);
}
private function setE(array $e) {
$this->ex3 = $e['key1'];
$this->ex4 = $e['key2'];
}
}
Related
i am trying to use this code:
$arr = [
function ($a) {
return $a + $a;
},
function ($b) {
return $b * $b;
},
function ($c,$cc) {
return $c % $cc - $c;
},
function ($d) {
return $d + 4 / $d;
}
];
how can i pass parameters to this functions?
i have already learned this statment for function with no arguments. for example:
function () { echo 'somethings'; } that's mean this function in an array don't have incoming arguments.
$test = rand (0,1);
echo $myarr[$test]();
In addition
can i change (rand) statment with other statment in the above code snippet?
You can do the following:
Your array:
$arr = [
function ($a) {
return $a + $a;
},
function ($b) {
return $b * $b;
},
function ($c,$cc) {
return $c % $cc - $c;
},
function ($d) {
return $d + 4 / $d;
}
];
Your rand
$test = rand(0,1);
---- note ----
you can change your rand() to any other statement provided that it an existing index of the $arr array. in order to know if $test value is an index which exists in the $arr array, you can do
if (isset($arr[$test])) {}
---- end note ---
to call the functions
$returnedValue = call_user_func($arr[$test], 10);
echo $returnedValue;
All over the place I have an array with a few elements, for example:
$myItem = [ 'a' => 10, 'b' => 20 ]
But but I would like to replace it with a class
$myClass = new MyOwnClass( 10, 20 );
$a = $myClass->GetSomeValue(); // this is the old 'a'
$b = $myClass->GetSomeOtherValue(); // this is the old 'b'
but for practical reasons I still want to be able to call
$a = $myClass['a'];
$b = $myClass['b'];
Is something like that possible in php?
Therefore, there is an interface named ArrayAccess. You have to implement it to your class.
class MyOwnClass implements ArrayAccess {
private $arr = null;
public function __construct($arr = null) {
if(is_array($arr))
$this->arr = $arr;
else
$this->arr = [];
}
public function offsetExists ($offset) {
if($this->arr !== null && isset($this->arr[$offset]))
return true;
return false;
}
public function offsetGet ($offset) {
if($this->arr !== null && isset($this->arr[$offset]))
return $this->arr[$offset];
return false;
}
public function offsetSet ($offset, $value) {
$this->arr[$offset] = $value;
}
public function offsetUnset ($offset) {
unset($this->arr[$offset]);
}
}
Use:
$arr = ["a" => 20, "b" => 30];
$obj = new MyOwnClass($arr);
$obj->offsetGet("a"); // Gives 20
$obj->offsetSet("b", 10);
$obj->offsetGet("b"); // Gives 10
Can you do something crazy like this
function cool_function($pizza, $ice_cream) {
make the arguments in the array into an array
return $array_of_paramaters // my new array
} // end function
print_r(cool_function); // outputs array(0 => pizza, 1=> ice cream)
Actually, this is pretty easy (and read the manual: func_get_args — Returns an array containing a function's argument list, see as well: Variable-length argument lists):
function cool_function($pizza, $ice_cream) {
return func_get_args();
}
but as asked in comments, why do you need this?
Or do you need the variable names? Reflection Docs is your friend:
function cool_named($neutron, $electron)
{
$f = new ReflectionFunction(__FUNCTION__);
$p = array();
foreach($f->getParameters() as $p1)
$p[] = '$'.$p1->name;
return $p;
}
var_dump(cool_named());
Or just both? (Edit: taking under-length, optional and over-length parameters into account):
function overall($neutron, $electron, $quark = 'xiaro')
{
$f = new ReflectionFunction(__FUNCTION__);
$defined = $f->getParameters();
$passed = func_get_args() + array_fill(0, count($defined), NULL);
foreach($defined as &$param)
$param = '$'.$param->name;
return array_combine($defined + array_keys($passed), $passed);
}
var_dump(overall('clara', 'peter', 'moon', 'jupiter'));
I'm not sure if you're looking for func_get_args which return all arguments passed to a function, or the ReflectionFunction class.
A basic example of func_get_args:
function cool_function($pizza, $ice_cream) {
return func_get_args();
}
But you don't need the arguments to make this work:
function cool_function() {
return func_get_args();
}
// cool_function(1,2,3) will return array(1,2,3)
The reflection option:
/**
* Returns an array of the names of this function
*/
function getMyArgNames($a,$b,$c)
{
$args = array();
$refFunc = new ReflectionFunction(__FUNCTION__);
foreach( $refFunc->getParameters() as $param ){
$args[] = $param->name;
}
return $args;
}
Or, for the really crazy:
/**
* Returns an associative array of the names of this function mapped
* to their values
*/
function getMyArgNames($a,$b,$c)
{
$received = func_get_args();
$i = 0;
$args = array();
$refFunc = new ReflectionFunction(__FUNCTION__);
foreach( $refFunc->getParameters() as $param ){
$args[$param->name] = $received[$i++];
}
// include all of those random, optional arguments.
while($i < count($received)) $args[] = $received[$i++];
return $args;
}
do you mean
function valuesToArray($value1,$value2){return array($value1,$value2);}
If I got you right, you so it like this:
function cool_function($pizza, $ice_cream) {
return array($pizza, $ice_cream);
}
but you could simply do that:
$new_var = array($pizza, $ice_cream);
Can a PHP function return a lot of vars without array?
I want like that:
<?php
public function a()
{
$a = "a";
$b = "b";
$c = "c";
}
echo a()->a;
echo a()->b;
echo a()->c;
?>
How can I access to $a,$b,$c vars?
Instead of an array, you could use an associative array and cast it to an object, which allows you to access the elements using the -> object syntax:
function a()
{
return (object) array(
'a' => "a",
'b' => "b",
'c' => "c");
}
echo a()->a; // be aware that you are calling a() three times here
echo a()->b;
echo a()->c;
function a1() {
return array(
'a' => 'a',
'b' => 'b',
'c' => 'c'
);
}
$a1 = a1();
echo $a1['a'];
echo $a1['b'];
echo $a1['c'];
function a2() {
$result = new stdClass();
$result->a = "a";
$result->b = "b";
$result->c = "c";
return $result;
}
$a2 = a2();
echo $a2->a;
echo $a2->b;
echo $a2->c;
// or - but that'll result in three function calls! So I don't think you really want this.
echo a2()->a;
echo a2()->b;
echo a2()->c;
http://php.net/manual/en/function.list.php
Create a class that holds your 3 variables and return an instance of the class. Example:
<?php
class A {
public $a;
public $b;
public $c;
public function __construct($a, $b, $c) {
$this->a = $a;
$this->b = $b;
$this->c = $c;
}
}
function a() {
return new A("a", "b", "c");
}
echo a()->a;
echo a()->b;
echo a()->c;
?>
Of course the last 3 lines are not particularly efficient because a() gets called 3 times. A sensible refactoring would result in those 3 lines being changed to:
$a = a();
echo $a->a;
echo $a->b;
echo $a->c;
If you want to access those variables that way (without using an array), you should better use a class:
class Name{
var $a = "a";
var $b = "b";
}
$obj = new Name();
echo $obj->a;
You could build a class and return an object instead. Check out this SO answer for something that you might find useful.
Yes this is possible when the return variable has to be as an array or it should be long string with multiple values separated with any of the delimiters like ", | #" and so on.
if it is built as an array we can receive it using var_dump function available in PHP
see below code
var_dump($array);
PHP Manual > Returning values:
A function can not return multiple values, but similar results can be obtained by returning an array.
<?php
function small_numbers()
{
return array (0, 1, 2);
}
list ($zero, $one, $two) = small_numbers();
no need for classes here.
PHP functions such as 'array_map' take a callback, which can be a simple function or a class or object method:
$array2 = array_map('myFunc', $array);
or
$array2 = array_map(array($object, 'myMethod'), $array);
But is there a syntax to pass a method which is bound within the iteration to the current object (like 'invoke' in Prototype.js)? So that the following could be used:
$array2 = array_map('myMethod', $array);
with the effect of
foreach($array as $obj) $array2[] = $obj->myMethod();
Obviously I can use this form, or I can write a wrapper function to make the call, and even do that inline. But since 'myMethod' is already a method it seems to be going round the houses to have to do one of these.
Not currently. When php 5.3 comes out, you could use the following syntax:
$array2 = array_map(function($obj) { return $obj->myMethod(); }, $array);
function obj_array_map($method, $arr_of_objects) {
$out = array();
$args = array_slice(func_get_args(), 2);
foreach ($arr_of_objects as $key => $obj) {
$out[$key] = call_user_func_array(Array($obj, $method), $args);
}
return $out;
}
// this code
$a = Array($obj1, $obj2);
obj_array_map('method', $a, 1, 2, 3);
// results in the calls:
$obj1->method(1, 2, 3);
$obj2->method(1, 2, 3);
Basically, no. There is no special syntax to make this any easier.
I can think of a fancier way of doing this in PHP 5.3, seeing as there's always more than one way to do things in PHP, but I'd say it wouldn't necessarily be better than your foreach example:
$x = array_reduce(
$array_of_objects,
function($val, $obj) { $val = array_merge($val, $obj->myMethod()); return $val; },
array()
);
Just go with your foreach :)
<?php
// $obj->$method(); works, where $method is a string containing the name of the
// real method
function array_map_obj($method, $array) {
$out = array();
foreach ($array as $key => $obj)
$out[$key] = $obj->$method();
return $out;
}
// seems to work ...
class Foo {
private $y = 0;
public function __construct($x) {
$this->y = $x;
}
public function bar() {
return $this->y*2;
}
}
$objs = array();
for ($i=0; $i<20; $i++)
$objs[] = new Foo($i);
$res = array_map_obj('bar', $objs);
var_dump($res);
?>
voila!
This is a bit of a silly answer, but you could subclass ArrayObject and use that instead of a normal array:
<?php
class ArrayTest extends ArrayObject {
public function invokeMethod() {
$result = array();
$args = func_get_args();
$method = array_shift($args);
foreach ($this as $obj) {
$result[] = call_user_func_array(array($obj, $method), $args);
}
return $result;
}
}
//example class to use
class a {
private $a;
public function __construct($a) {
$this->a = $a;
}
public function multiply($n) {
return $this->a * $n;
}
}
//use ArrayTest instance instead of array
$array = new ArrayTest();
$array[] = new a(1);
$array[] = new a(2);
$array[] = new a(3);
print_r($array->invokeMethod('multiply', 2));
Outputs this:
Array
(
[0] => 2
[1] => 4
[2] => 6
)
I would use create_function() to ... well ... create a temporary function for array_map while waiting for PHP 5.3
$func = create_function('$o', '$o->myMethod();');
array_map($func, $objects);