Sorting array of objects by function in PHP - php

Let's say I have an object called ACCOUNT like:
class ACCOUNT
{
private $contact;
public function getContact();
}
and another object CONTACT:
class CONTACT
{
private $lastName;
public function getLastName()
{
return $this->lastName;
}
}
Then I create an array of these objects $accountArray = ACCOUNT::get();
How can I sort this array alphabetically by something like $account->getContact()->getLastName();?
What I've tried:
class Account
{
private $contact;
public function getContact();
public static function cmp($a,$b)
{
$al = strtolower($a->getContact()->getLastName());
$bl = strtolower($b->getContact()->getLastName());
if ($al == $bl) {
return 0;
}
return ($al > $bl) ? +1 : -1;
}
public static function sortByLastName($accountArray)
{
usort($moACOUNTArray, array('ACCOUNT', 'cmp'));
}
}
But I get this error:
Call to undefined method ACCOUNT::getContact()

You can use usort function of PHP, like mentioned in comments. There is self-explaining example:
Try this code:
<?php
class ACCOUNT
{
private $contact;
public function getContact()
{
return $this->contact;
}
public function setContact($v)
{
$this->contact = $v;
}
}
class CONTACT
{
private $lastName;
public function getLastName()
{
return $this->lastName;
}
public function setLastName($v)
{
$this->lastName = $v;
}
}
//create data for testing
$c1 = new CONTACT;
$c1->setLastName('aaaa');
$a1 = new ACCOUNT;
$a1->setContact($c1);
$c2 = new CONTACT;
$c2->setLastName('zzz');
$a2 = new ACCOUNT;
$a2->setContact($c2);
$c3 = new CONTACT;
$c3->setLastName('ggg');
$a3 = new ACCOUNT;
$a3->setContact($c3);
$array = array($a1, $a2, $a3);
//making sort
function cmp($a, $b)
{
return strcmp($a->getContact()->getLastName(), $b->getContact()->getLastName());
}
usort($array, "cmp");
//showing sort result
echo '<pre>';
print_r($array);
Result is:
Array
(
[0] => ACCOUNT Object
(
[contact:ACCOUNT:private] => CONTACT Object
(
[lastName:CONTACT:private] => aaaa
)
)
[1] => ACCOUNT Object
(
[contact:ACCOUNT:private] => CONTACT Object
(
[lastName:CONTACT:private] => ggg
)
)
[2] => ACCOUNT Object
(
[contact:ACCOUNT:private] => CONTACT Object
(
[lastName:CONTACT:private] => zzz
)
)
)

Related

PHP class arrays

I have created a class to get user parameters like below, but im having trouble showing data.
Here is what I have done:
namespace App\Users;
class Person
{
public $_user;
public $_userDataParams;
public function __construct($user)
{
$this->_user = $user;
$this->_userDataParams = self::$this->getData();
}
public function function_1()
{
$obj[$this->_user]['user_fullname'] = 'John Doe';
$obj[$this->_user]['user_role'] = 'Button-Pusher';
$this->_userDataParams = $obj;
return $this->_userDataParams;
}
public function function_2()
{
$obj[$this->_user]['experience'] = '4 Months';
$obj[$this->_user]['experience_date'] = '2017-01-01';
$this->_userDataParams = $obj;
return $this->_userDataParams;
}
public function getData()
{
$this->_userDataParams = array_merge(self::$this->function_1(),self::$this->function_2());
return $this->_userDataParams;
}
}
echo "<pre>";
$person = new Person("john");
print_r($person);
This is what it prints :
App\Users\Person Object
(
[_user] => john
[_userDataParams] => Array
(
[john] => Array
(
[experience] => 4 Months
[experience_date] => 2017-01-01
)
)
)
I need to add to _userDataParams also function_1 array of data.
Can someone help please.
Thank you.

Singleton class, multidimensional array unset element

I am trying to remove irrelevant data from a multidimensional array.
The array is looking like this:
[6] => Array
(
[710C27E0-822A-4513-9D44-D97E929484A9] => Array
(
[documents] => Array
(
[0] => error message
)
)
)
And i am using the following code:
<?php
class report {
private static $instance;
private $data = array();
private function __construct() { }
private function __clone() { }
public function __destruct() { }
public static function singleton() {
if (!isset(self::$instance))
self::$instance = new self();
return self::$instance;
}
public function check() {
foreach($this->data as $key => &$values) {
foreach($values as $k => &$value) {
/* some checks */
if($return != null)
$values[$return] = $values[$k];
unset($values[$k]);
}
if(sizeof($values) == 0)
unset($this->data[$key];
}
}
public function __toString() {
print_r($this->data);
return '';
}
}
When i replace upper check function by the following code it is working, but i am looking for some better/cleaner and especially faster solution.
public function check() {
$_data = json_encode($this->data);
$data = json_decode($_data);
foreach($data as $key => &$values) {
foreach($values as $k => &$value) {
/* some checks */
if($return != null)
$values->$return = $values->$k;
unset($values->$k);
}
}
$this->data = $data;
}
SOLVED but not understanding it..
public function log($id, $guid, $job, $message) {
$this->data[$id][$guid][$job][] = $message;
}
when i var_dump($guid) it returns:
string(36) "710C27E0-822A-4513-9D44-D97E929484A9"
now i did a string cast:
var_dump((string)$guid);
returning:
string(36) "710C27E0-822A-4513-9D44-D97E929484A9"
but
$this->data[$id][(string)$guid][$job][] = $message;
works!

How can I get all the public property values of a 'last descendant' object in php?

The code below makes this easier to explain :
<?php
class a
{
public $dog = 'woof';
public $cat = 'miaow';
private $zebra = '??';
}
class b extends a
{
protected $snake = 'hiss';
public $owl = 'hoot';
public $bird = 'tweet';
}
$test = new b();
print_r(get_object_vars($test));
Currently this returns:
Array
(
[owl] => hoot
[bird] => tweet
[dog] => woof
[cat] => miaow
)
what can I do to find properties that were only defined or set in class b (eg just owl and bird)?
Use ReflectionObject for this:
$test = new b();
$props = array();
$class = new ReflectionObject($test);
foreach($class->getProperties() as $p) {
if($p->getDeclaringClass()->name === 'b') {
$p->setAccessible(TRUE);
$props[$p->name] = $p->getValue($test);
}
}
print_r($props);
Output:
Array
(
[snake] => hiss
[owl] => hoot
[bird] => tweet
)
getProperties() will return all properties of the class. I'm using $p->getDeclaringClass() afterwards to check if the declaring class is b
Additionally this can be generalized to a function:
function get_declared_object_vars($object) {
$props = array();
$class = new ReflectionObject($object);
foreach($class->getProperties() as $p) {
$p->setAccessible(TRUE);
if($p->getDeclaringClass()->name === get_class($object)) {
$props[$p->name] = $p->getValue($object);
}
}
return $props;
}
print_r(get_declared_object_vars($test));

Get single value from an array

I have below array result
Array ( [0] => Item Object ( [name:protected] => My Super Cool Toy [price:protected] => 10.99 ) )
I need to get [name:protected] => My Super Cool Toy from this array.
Please tell me how to get it,
I will paste my classes below
class ShoppingCart
{
private $items = array();
private $n_items = 0;
function addItem( Item $item )
{
$this->items[] = $item;
$this->n_items = $this->n_items + 1;
print_r($this->items);
}
}
and
class Item {
protected $name;
protected $price;
public function __construct($name, $price) {
$this->name = $name;
$this->price = $price;
}
public function getName() {
echo "item is $this->name";
return $this->name;
}
public function getPrice() {
return $this->price;
}
}
and
require_once('AddingMachine.php');
require_once('item.php');
//$arrayofnumbers = array(100,200);
$objectname = new ShoppingCart();
$objectname->addItem(new Item('My Super Cool Toy', 10.99));
$obname = new Item($items,44);
$obname->getName();
Thanks
If I got it correctly, you got this array in ShoppingCart class, in method addItem, so to access it you just use corresponding getter method, e.g.:
$this->items[0]->getName();
You can try :
$objectname = new ShoppingCart();
$objectname->addItem(new Item('My Super Cool Toy', 10.99));
foreach ( $objectname->getItems() as $item ) {
echo $item->getName(), PHP_EOL;
}
Modified Class
class ShoppingCart {
private $items = array();
private $n_items = 0;
function addItem(Item $item) {
$this->items[] = $item;
$this->n_items = $this->n_items + 1;
}
function getItems($n = null) {
return $n === null ? $this->items : (isset($this->items[$n]) ? : $this->items[$n]);
}
}

using the magic __set() method with 2D arrays

If I have the following registry class:
Class registry
{
private $_vars;
public function __construct()
{
$this->_vars = array();
}
public function __set($key, $val)
{
$this->_vars[$key] = $val;
}
public function __get($key)
{
if (isset($this->_vars[$key]))
return $this->_vars[$key];
}
public function printAll()
{
print "<pre>".print_r($this->_vars,true)."</pre>";
}
}
$reg = new registry();
$reg->arr = array(1,2,3);
$reg->arr = array_merge($reg->arr,array(4));
$reg->printAll();
Would there be an easier way to push a new item onto the 'arr' array?
This code: 'array[] = item' doesn't work with the magic set method, and I couldn't find any useful info with google. Thanks for your time!
If you have:
$reg = new registry();
$reg->arr = array(1,2,3);
$reg->arr = 4;
And you're expecting:
Array
(
[arr] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
)
All you need to do is update your __set method to:
public function __set($key, $val){
if(!array_key_exists($key, $this->_vars)){
$this->_vars[$key] = array();
}
$this->_vars[$key] = array_merge($this->_vars[$key], (array)$val);
}
You need to alter the definition of __get() so that it returns by reference:
public function &__get($key) {
return $this->_vars[$key];
}

Categories