Simulating JavaScript extension functions - php

I was wondering if I can, in PHP, like JavaScript, apply a function call to the return of an object. In JavaScript I can do this:
var y = 1;
var x = y.toString().concat(' + 1');
console.log(x);
And I think if it is possible to do almost the same in PHP. I was thinking in recursion to this and I didn't know exactly the name to search for it. I'm trying, in the moment:
<?php
class Main {
public function __construct() {
$this->Main = new Main;
}
public function merge(/* this */ $xs, $ys) {
return array_merge($xs, $ys);
}
public function add(/* this */ $xs, $ys) {
return array_push($xs, $ys);
}
}
$aux = new Main;
$x = $aux -> merge([1, 2, 3], [4, 5, 6])
-> add(7)
-> add(8)
-> add(9);
// $x => [1, 2, 3, 4, 5, 6, 7, 8, 9]
?>
This is overflowing everything. I receive an overflow message:
Maximum function nesting level of '100' reached
Am I able to do this, like in JavaScript? Almost the same as C# extension methods.

Its called method chaining:
class Main {
private $ar = array();
public function merge($xs, $ys) {
$this->ar = array_merge($xs, $ys);
return $this;
}
public function add($ys) {
$this->ar[]= $ys;
return $this;
}
public function toArray(){
return $this->ar;
}
//if you want to echo a string representation
public function __toString(){
return implode(',', $this-ar);
}
}
$aux = new Main;
$x = $aux->merge([1, 2, 3], [4, 5, 6])->add(7)->add(8)-> add(9);
echo $x;
var_dump($x->toArray());

You can work with the returns from functions, but it’s not as nice-looking as JavaScript:
<?php
$array1 = array(1, 2, 3);
$array2 = array(4, 5, 6);
$x = array_push(array_push(array_push(array_merge($array1, $array2), 7), 8), 9);
$x should then be an array containing the numbers 1 through 9.

Related

PHP class that sorts an ordered integer array with the help of sort() function

I have written down the following for the above question
<?php
class sortClass{
public function __construct(array $arrayPassed){
return sort($arrayPassed);
}
}
$newarray=array(11,-2,4,35,0,8,-9);
$sorted = new sortClass($newarray);
print_r($sorted);
?>
And the output is 'sortClass Object()' , I'd like some help to understand why it would not print out the sorted array , When we instantiate a class - the constructor will automatically execute and return what ever it returns right? so why isn;t printing $sorted object printing whats returned in the constructor?
You don't need a wrapper class just to sort, you can just run sort function directly, the issue with your code is, returning in __constructor.
I suggest you run it directly like this:
<?php
$newarray = array(11,-2,4,35,0,8,-9);
sort($newarray);
print_r($newarray);
?>
or this one if you still need a OOP version:
<?php
class sortClass{
private $arrayPassed = [];
public function __construct(array $arrayPassed){
$this->arrayPassed = $arrayPassed;
}
public function sort() {
sort($this->arrayPassed);
return $this->arrayPassed;
}
}
$newarray = array(11,-2,4,35,0,8,-9);
$sortClass = new sortClass($newarray);
print_r($sortClass->sort());
https://www.php.net/manual/en/language.oop5.basic.php
You misunderstood OOP, you need to learn about it before write code.
I give a workaround just for the idea:
class sortClass
{
public $sorted;
public function __construct(array $arrayPassed)
{
sort($arrayPassed);
$this->sorted = $arrayPassed;
}
}
$newarray = array(11, -2, 4, 35, 0, 8, -9);
$sorted = new sortClass($newarray);
var_dump($sorted->sorted);
You can't return anything from a constructor method. You have to create a new public method which return the sorted the value.
class MyClass
{
private $sorted;
public function __construct(array $input)
{
$this->sorted = asort($input);
}
public function sortedArray()
{
return $this->sorted;
}
}
$arr = [11, -2, 4, 35, 0, 8, -9];
$sorted = new MyClass($arr);
print_r($sorted->sortedArray());
AS Nigel Ren explain you can't return from a constructor method. You need a new method to return the sorted the value. Check my code
class sortClass{
private $sortedArray;
public function __construct(array $arrayPassed){
$this->sortedArray = asort($arrayPassed);
}
public function getSortedArray(){
return $this->sortedArray;
}
}
$newarray=array(11,-2,4,35,0,8,-9);
$sorted = new sortClass($newarray);
print_r($sorted->getSortedArray());

How to calculate arrays of objects intersection with custom comparison function?

I have two arrays of objects and I need to get array of objects which are present in both arrays, comparing them with custom callback function.
Here is my code:
<?php
class Some {
public $prop1;
public $prop2;
public function __construct($prop1, $prop2)
{
$this->prop1 = $prop1;
$this->prop2 = $prop2;
}
}
$arr1 = [new Some(1, 2), new Some(2, 3), new Some(3, 4)];
$arr2 = [new Some(2, 3), new Some(1, 2)];
$intersection = array_uintersect($arr1, $arr2, function ($el1, $el2) {
return ($el1->prop1 === $el2->prop1) && ($el1->prop2 === $el2->prop2) ? 0 : 1;
});
print_r($intersection);
And what I get is:
Array (
[1] => Some Object
(
[prop1] => 2
[prop2] => 3
)
)
While I obviously want to get two objects which props are identical ((1, 2) and (2, 3).
What's wrong with this uintersect? How to achieve what I need?
Intersect function first sorted arrays, so you need have understanding haw one object less than another, and return -1, 0, 1 as result of comparing. Else, if you only can answer that objects are equal or not, you should scan second array for each item of the first one – splash58 13 mins ago. Now result of the code depends on order of objects in your arrays
To use intersect function you can create a function to compare two objects as below
class Some {
public $prop1;
public $prop2;
static function compare($el1, $el2) {
$r = $el1->prop1 - $el2->prop1;
return $r ? $r : ($el1->prop2 - $el2->prop2);
}
public function __construct($prop1, $prop2)
{
$this->prop1 = $prop1;
$this->prop2 = $prop2;
}
}
$arr1 = [new Some(1, 2), new Some(2, 3), new Some(3, 4)];
$arr2 = [new Some(2, 3), new Some(1, 2)];
$intersection = array_uintersect($arr1, $arr2, ['Some','compare']);
print_r($intersection);
demo
UPDATE
If you don't want to make function to compare objects, PHP itself checks that such objects are equal. So you can use simple code with in_array function
$intersection = array();
foreach($arr1 as $x) {
if (in_array($x, $arr2)) {
$intersection[] = $x;
}
}
print_r($intersection);

PHP: Calling a function in the argument of another function

What's the syntax of calling a function in another function in php?
I want something like:
function argfunction($a,$b,$c){
}
function anotherfunction(argfunction($a,$b,$c), $d, $e)
{
}
I am not calling argfunction again in the definition of anotherfunction
The parameters of a function should be declarative, i.e. they are not supposed to do something.
But you can do this with the callable keyword (PHP 5.4):
function argfunction($a,$b,$c){
return $a+$b+$c;
}
function anotherfunction(callable $a_func, $a, $b, $c, $d, $e) {
// call the function we are given:
$abc = $a_func($a, $b, $c);
return $abc + $d * $e;
}
// call:
anotherfunction ("argfunction", 1, 2, 3, 4, 5); // output: 26
Or you can pass the whole function definition:
echo anotherfunction (function ($a, $b, $c) {
return $a+$b+$c;
}, 1, 2, 3, 4, 5); // output: 26
Or, assign a function to a variable, and pass that:
$myfunc = function ($a, $b, $c) {
return $a+$b+$c;
};
echo anotherfunction ($myfunc, 1, 2, 3, 4, 5); // output: 26
But if you just want to pass the result of a function call to another function, then it is much more straightforward:
function anotherfunction2($abc, $d, $e) {
return $abc + $d * $e;
}
echo anotherfunction2 (argfunction(1, 2, 3), 4, 5); // output: 26
Does not make sense but I will assume that you are expressing your idea in a wrong way.
Would you maybe looking for something similar to callback?
Take a look at the following: here and here

An object that can be used as an array as well

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

PHPUnit: Calling methods inside dataprovider

Is there anyway I can call a method within the dataprovider method? I tried doing it but the value passed from the dataProvider to the testAdd() method won't just pass. How do I do this?
PS: I do not want to call this from setUp() or setUpBeforeClass(), any way out?
<?php
class DataTest extends PHPUnit_Framework_TestCase
{
/**
* #dataProvider additionProvider
*/
public function testAdd($a, $b, $expected, $someValue)
{
echo $someValue;
$this->assertEquals($expected, $a + $b);
}
public function additionProvider()
{
$someValue = $this->doSomething();
return array(
array(0, 0, 0, $someValue),
array(0, 1, 1, $someValue),
array(1, 0, 1, $someValue),
array(1, 1, 3, $someValue)
);
}
protected function doSomething(){
return 5 * 6;
}
}
?>
Thanks

Categories