define if statement for object [duplicate] - php

This question already has answers here:
how to create a php class which can be casted to boolean (be truthy or falsy)
(7 answers)
Closed 8 years ago.
Is there a way to define the boolean returned value for an if statement issued on my class instances?
I have a class implementing the array access interface and so on, but even if the wrapped array is empty:
if($class)
will always return true, since it is an object and does exists.
I'd rather not have to issue everytime an:
if(count($class))
Is there any way to achieve this?

If I get the point you can implement the countable interface; This requires you define the count() method, which let you know (by using it like count($myArrayAccessInstance)) if your internal array has items or not o whatever logic you want to define.
class MyAy implements ArrayAccess, Countable
{
private $data;
public function offsetExists($key)
{
# code...
}
public function offsetUnset($key)
{
# code...
}
public function offsetGet($key)
{
# code...
}
public function offsetSet($key, $value)
{
$this->data[$key] = $key;
}
public function count()
{
return $this->data > 0;
}
}
$my = new MyAy();
$my['user'] = "Ilpaijin";
if(count($my))
{
var_dump($my);
}

Given that you are implementing a class, maybe you could have a member which counts the elements in the array? Something like:
class MyClass {
public $numElems = 0;
private $elems = array();
...
public function add($elem) {
$elems[] = $elem;
$numElems++;
}
...
}
And then, do the iflike if($class->numElems) ...

Its not possible
In PHP an object when cast to bool always produces true. There is no way of changing that.
Check answers here

It's impossible to cast an object to a boolean related to a property inside the class because it always will return true. but I think you just need to create a function inside your class that allows you to return the boolean you need like this
public function bool()
{
return (count($this->array)>0);
}
when you need to use it, just call the function like this if ($obj->bool()) { ... } and another way to make your statements look like what you wanted to do in the begining is to define a class with a really short name, I usually use _, and this function should return the boolean you need just like this
function _ ($Obj)
{
return $Obj->bool();
}
finally, instead of testing on your class like this if ($class->bool()) which is a bit long, you do it like this
if (_($class))
{ /* do something fun */ }

Related

Make a variable behave like a function

I'm making a PHP script which works with polynomials and monomials (an example of monomial is 42xk^2c^3d). The Monomial class is defined as follows:
class Monomial {
public $coefficient; // i.e. 42
public $letters; // an array of Letter objects
public $literal; // i.e. xk^2c^3d
/* Code */
}
Now, in my applications I use both the array of letters and the literal variable. I don't want to update "by hand" the literal variable whenever I update the monomial (e.g. when adding something to it): instead, I want it to be dynamical, so that accessing it calls a function to "build" it. Any ideas?
Write a function setLetters (or even updateMonomial) which updates both your variables and use that instead of accessing the variable directly. It's generally a good idea to not expose class members.
Use the __get method. An example:
class Monomial {
public $coefficient;
public $letters;
public $literal;
function __get($var) {
if ($var != "literal") {
return $this->data[$var];
} else {
foreach ($this->letters as $letter) {
$return.=$letter->literal;
}
return $return;
}
}
There would be a similar __get method in the Letter object which would generate the literal string on request.

php class and arrays madness at least for me

So there are two things that I am stuck on now. First
class DisplayTaxonomy {
public $MyArray[]= new DisplayTaxonomy(); //the compiler says syntax error
//things I have tried
//public $ss[]= new Object();
}
Second! in a function like this:
public function whatever()
{
$Temp = new DisplayTaxonomy();
$Temp->setADTitle("1");
$MyArray[]= $Temp;//works just fine.
//then i tried to return the array
return $MyArray[];
}
I get the following
//Cannot use [] for reading in C:\xampp\htdocs\wordpress\wp-//content\themes\twentyeleven\page.php on line 52
then in the client side
$y=new DisplayTaxonomy();
$myArray[]=new DisplayTaxonomy();//works fine dont know why I cant do this in theclass.
$myArray[]=$y->getArrayOfDisplayTaxonomyObjects();
echo $myArray[0]->getADTitle();
It seems you want to create a class that handles a collection of Taxonomy objects. In that case you should have two classes, instead of making a class store instances of itself.
class TaxonomyContainer
{
private $collection = array();
public function addElement(DisplayTaxonomy $element)
{
$this->collection[] = $element;
}
public function getElements()
{
return $this->collection;
}
}
class DisplayTaxonomy
{
private $adTitle;
public function setAdTitle($adTitle)
{
$this->adTitle = $adTitle;
}
//and other functionality the Taxonomy object should have
}
Then you can avoid the ugly self replicating behaviour and separate your concerns.
$container = new TaxonomyContainer();
$element = new DisplayTaxonomy();
$container->addElement($element);
On the next level, it might be worth considering the use of one of PHP's predefined interfaces for the Container class.
You declare objects in the function body and initiate them in the constructor (or a member function). You don't use [] when returning an array, $array[] has the same functionality as array_push, nothing more.
To clarify,
class myClass {
public $obj = array();
public function __construct() {
$this->obj[] = new OtherObject();
}
public function getObj() {
return $this->obj;
}
}
You cannot do this :
class DisplayTaxonomy {
public $MyArray[]= new DisplayTaxonomy();
}
because it's like an infinite loop :) So you have to use __contruct() function.
After change the :
return $MyArray[];
to :
return $MyArray;
Your first issue is due to trying to call the class you're declaring.
class DisplayTaxonomy {
public $MyArray[]= new DisplayTaxonomy();
You should initialize your object outside of the class, in the portion of code that you need to reference the class.
In addition, the object is already an array so you can omit attaching [] to the end return $MyArray:
public function whatever(){
$Temp = new DisplayTaxonomy();
$Temp->setADTitle("1");
$MyArray[] = $Temp;
return $MyArray;
}
You're declaring the array object here:
$MyArray[]= $Temp;//works just fine
You can't call code (new DisplayTaxonomy()) when definining class properties. You'll have to assign the value in the constructor of the class:
class Foo
{
public $MyArray;
public function __construct()
{
$this->MyArray = new DisplayTaxonomy();
}
}
The other issue is that the $array[] shortcut is for appending to an array. If you want to just return the array (and not write to the array which you're asking about with []), simply skip []:
return $MyArray;
Expanded:
As Vincent Joigƞie pointed out below; you're trying to create a class with the same name as the class you're already creating. This doesn't make any sense, except for static properties. In that case you can't use __construct(), but would rather create / set the object in the static method you're calling to retrieve the object the first time:
static public function getInstance()
{
if (self::$MyArray === null)
{
self::$MyArray = new DisplayTaxonomy();
}
return self::$MyArray;
}
This is however probably not what you want, and it seems you've confused something in your logic in your class definition. Guessing freely you might just want:
class Foo
{
public $MyArray = array();
}
As array() is a static assignment (and not a function call), it's allowed in the class definition.

PHP object method doesn't behave as I expect

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)

Assigning a function's result to a variable within a PHP class? OOP Weirdness

I know you can assign a function's return value to a variable and use it, like this:
function standardModel()
{
return "Higgs Boson";
}
$nextBigThing = standardModel();
echo $nextBigThing;
So someone please tell me why the following doesn't work? Or is it just not implemented yet? Am I missing something?
class standardModel
{
private function nextBigThing()
{
return "Higgs Boson";
}
public $nextBigThing = $this->nextBigThing();
}
$standardModel = new standardModel;
echo $standardModel->nextBigThing; // get var, not the function directly
I know I could do this:
class standardModel
{
// Public instead of private
public function nextBigThing()
{
return "Higgs Boson";
}
}
$standardModel = new standardModel;
echo $standardModel->nextBigThing(); // Call to the function itself
But in my project's case, all of the information stored in the class are predefined public vars, except one of them, which needs to compute the value at runtime.
I want it consistent so I nor any other developer using this project has to remember that one value has to be function call rather then a var call.
But don't worry about my project, I'm mainly just wondering why the inconsistency within PHP's interpreter?
Obviously, the examples are made up to simplify things. Please don't question "why" I need to put said function in the class. I don't need a lesson on proper OOP and this is just a proof of concept. Thanks!
public $nextBigThing = $this->nextBigThing();
You can only initialize class members with constant values. I.e. you can't use functions or any sort of expression at this point. Furthermore, the class isn't even fully loaded at this point, so even if it was allowed you probably couldn't call its own functions on itself while it's still being constructed.
Do this:
class standardModel {
public $nextBigThing = null;
public function __construct() {
$this->nextBigThing = $this->nextBigThing();
}
private function nextBigThing() {
return "Higgs Boson";
}
}
You can't assign default values to properties like that unless that value is of a constant data type (such as string, int...etc). Anything that essentially processes code (such as a function, even $_SESSION values) can't be assigned as a default value to a property. What you can do though is assign the property whatever value you want inside of a constructor.
class test {
private $test_priv_prop;
public function __construct(){
$this->test_priv_prop = $this->test_method();
}
public function test_method(){
return "some value";
}
}
class standardModel
{
// Public instead of private
public function nextBigThing()
{
return "Higgs Boson";
}
}
$standardModel = new standardModel(); // corection
echo $standardModel->nextBigThing();

how can I get around no arrays as class constants in php?

I have a class with a static method. There is an array to check that a string argument passed is a member of a set. But, with the static method, I can't reference the class property in an uninstantiated class, nor can I have an array as a class constant.
I suppose I could hard code the array in the static method, but then if I need to change it, I'd have to remember to change it in two places. I'd like to avoid this.
You can create a private static function that will create the array on demand and return it:
class YourClass {
private static $values = NULL;
private static function values() {
if (self::$values === NULL) {
self::$values = array(
'value1',
'value2',
'value3',
);
}
return self::$values;
}
}
I put arrays in another file and then include the file wherever I need it.
I am having a really really hard time understanding your question. Here is essentially what I understood:
I need to maintain a proper set, where
no two elements are the same.
PHP does not have a set type, not even in SPL! We can emulate the functionality of a set but any solution I can think of is not pleasant. Here is what I think is the cleanest:
<?php
class Set {
private $elements = array();
public function hasElement($ele) {
return array_key_exists($ele, $elements);
}
public function addElement($ele) {
$this->elements[$ele] = $ele;
}
public function removeElement($ele) {
unset($this->elements[$ele]);
}
public function getElements() {
return array_values($this->elements);
}
public function countElements() {
return count($this->elements);
}
}
Example usage:
<?php
$animals = new Set;
print_r($animals->getElments());
$animals->addElement('bear');
$animals->addElement('tiger');
print_r($animals->getElements());
$animals->addElement('chair');
$animals->removeElement('chair');
var_dump($animals->hasElement('chair'));
var_dump($animals->countElements());

Categories