How to access array values inside class object? - php

I have a array like this in a function:
$value = array("name"=>"test", "age"=>"00");
I made this $value as public inside the class abc.
Now in my other file, I want to access the values from this array, so I create an instance by:
$getValue = new <classname>;
$getValue->value..
I'm not sure how to proceed so that then I can access each element from that array.

You mentioned that $value is in a function, but is public. Can you post the function, or clarify whether you meant declaring or instantiating within a function?
If you're instantiating it that's perfectly fine, and you can use the array keys to index $value just like any other array:
$object = new classname;
$name = $object->value["name"];
$age = $object->value["age"];
// Or you can use foreach, getting both key and value
foreach ($object->value as $key => $value) {
echo $key . ": " . $value;
}
However, if you're talking about declaring public $value in a function then that's a syntax error.
Furthermore if you declare $value (within a function) without the public modifier then its scope is limited to that function and it cannot be public. The array will go out of scope at the end of the function and for all intents and purposes cease to exist.
If this part seems confusing I recommend reading up on visibility in PHP.

The same as you would normally use an array.
$getValue = new yourClass();
$getValue->value['name'];

Use code
foreach($getValue->value as $key=>$value)

<?php
interface Nameable {
public function getName($i);
public function setName($a,$name);
}
class Book implements Nameable {
private $name=array();
public function getName($i) {
return $this->name[$i];
}
public function setName($i, $name) {
return $this->name[$i] = $name;
}
}
$interfaces = class_implements('Book');
if (isset($interfaces['Nameable'])) {
$bk1 = new Book;
$books = array('bk1', 'bk2', 'bk3', 'bk4', 'bk5');
for ($i = 0; $i < count($books); $i++)
$bk1->setName($i, $books[$i]);
for ($i = 0; $i < count($books); $i++)
echo '// Book implements Nameable: ' . $bk1->getName($i) . nl();
}
?>

Related

Why does creating object inside the class invoke another function instead of $this?

public static function instantiation($row){
>>> $users = new self;
foreach ($row as $the_attribute => $value) {
if($users ->has_the_attribute($the_attribute)){
$users ->{$the_attribute} = $value;
}
}
return users;
}
private function has_the_attribute($the_attribute){
$object_properties = get_object_vars($this);
$array_result = array_key_exists($the_attribute, $object_properties);
return $array_result;
}
May I know why do I have do create an object to here in order to invoke has_the_attribute() function? What is the problem here if I use $this->has_the_attribute and $this->$the_attribute instead of $users->$the_attribute?
When iterating $result you get pairs of attribute-name/attribute-value, so $the_db_attribute is the variable containing the current attribute-name.
In $the_object -> $the_db_attribute = $value; we guess that $the_object has properties which are attribute-names.
So if current $the_db_attribute is, say, "the_first_attribute", then your puzzling line is equivalent to $the_object -> the_first_attribute = $value;, which is not puzzling at all now :)
It's assigning a property whose name is the value of $the_db_attribute, and setting its value to $value. So if $the_db_attribute = "foo", it's equivalent to
$the_object->foo = $value;
So what this is doing is filling in the properties in the object with the corresponding elements in the $result array.

Convert String To Object-Variable-Name?

i want to turn a simple string like that "response->dict->words" into a variable name that i can actually work with. I will give an example now. Lets assume the value of $response->dict->words is 67.
Example:
$var = "response->dict->words"
echo $$var; /* PRINT THE VALUE 67 FROM $response->dict->words*/
As you may notice i put an extra dollar sign before the $var because this should work, but it doesn't.
Can anyone help me with this?
class ClassOne {
public function test() {
return 'test';
}
}
class ClassTwo {
public function test2() {
return 'test2';
}
}
$one = new ClassOne();
$two = new ClassTwo();
$objects = array('one', 'two');
$methods = array('test', 'test2');
for ($i = 0; $i < count($objects); $i++) {
echo ${$objects[$i]}->$methods[$i]();
}
You can store classnames or method names as strings and later use them, or even store variable names, like here ${$objects} (variable variables), but you cannot store whole logic.
To evaluate whole logic, you have to use eval(), which is most probably bad idea
$var = "response->dict->words"
eval("?> <?php echo $".$var.";");
You can split your string and make the call as below:
class Response {
public $dict;
public function __construct() {
$this->dict = new stdClass();
$this->dict->words = 'words test';
}
}
$response = new Response();
$var = 'response->dict->words';
$elements = explode('->', $var);
echo ${$elements[0]}->$elements[1]->$elements[2];
Results into words test
Or, if you don't know the level of nesting the object call, you can perform the call in a foreach loop. When the loop exits, the last call will be available after it:
class Response {
public $dict;
public function __construct() {
$this->dict = new stdClass();
$this->dict->words = new stdClass();
$this->dict->words->final = 'test chained string';
}
}
$response = new Response();
$var = 'response->dict->words->final';
$elements = explode('->', $var);
foreach ($elements as $key => $element) {
if ($key == 0) {
$call = ${$element};
continue;
}
$call = $call->$element;
}
echo $call;
Results into: test chained string
There is a better way, why don't you cache the variable like
$var = $response->dict->words;

PHP/JS: Removing final comma in a delimited list

What is the best, most concise coding practice for eliminating the final comma when generating a comma-delimted list in a typical for loop? This comes up ALL THE TIME and I cannot stand writing so many extra lines of code for something so simple... there must be a better technique/pattern.
foreach ($list as $item)
{
echo "'".$item . "',";
}
What is the best way (using PHP and/or JS) to make the above code produce a comma everywhere but the last iteration?
Right now I am doing something like this:
$total = count($images);
$i=0;
foreach ($list as $item)
{
$i++;
echo "'".$item."'";
if ($i<$total) echo ',';
}
But this adds FOUR LINES OF CODE for something so simple...
The Standard PHP Library (SPL) offers a handy class, CachingIterator that can be used to see if there are any more items to be iterated over. The following may not be as concise as you would like but it is flexible (i.e. can be used for far more than just arrays).
$array = range('a', 'g');
$cache = new CachingIterator(new ArrayIterator($array));
foreach ($cache as $item) {
echo "'$item'";
if ($cache->hasNext()) {
echo ',';
}
}
The above example outputs
'a','b','c','d','e','f','g'
In case you didn't simplified the code example:
echo implode(',', $list);
does it (see also implode PHP Manual ).
If there is more code within the foreach loop you need to keep track whether or not you're on the last element and deal with the situation:
$count = count($list);
$current = 0;
foreach ($list as $item)
{
$current++;
$notLast = $current !== $count;
echo $item;
if ($notLast) echo ',';
}
Edit: you added a similar code to the question after I answered this, so if that is too burdensome for your coding fingers and especially (and understandable) you don't want to repeat such code all day long the same, you need to encapsulate it for re-use. One solution is to implement this within a re-useable iterator:
$list = array('a', 'b', 'c');
class PositionKnowingIterator implements iterator
{
/**
* #var iterator
*/
private $inner;
private $count;
private $index;
public function __construct(array $list) {
// NOTE: implement more iterators / objects to deal with in here
// if you like. This constructor limits it to arrays but
// more is possible.
$this->count = count($list);
$this->inner = new ArrayIterator($list);
}
/* SPL iterator implementation */
public function current() {
return $this->inner->current();
}
public function next() {
$this->index++;
$this->inner->next();
}
public function key() {
$this->inner->key();
}
public function rewind() {
$this->index = 1;
$this->inner->rewind();
}
public function valid() {
return $this->inner->valid();
}
/* Position Knowing */
public function isLast() {
return $this->index === $this->count;
}
public function notLast() {
return !$this->isLast();
}
public function isFirst() {
return $this->index === 1;
}
public function notFirst() {
return !$this->isFirst();
}
public function isInside() {
return $this->notFirst() && $this->notLast();
}
}
foreach($iterator = new PositionKnowingIterator($list) as $item)
{
echo "'".$item."'", $iterator->notLast() ? ',' : '';
}
echo implode(",", $list);
without using foreach needed
User implode() function to achieve this. Sometimes it's also necessary to put something around, for example, to quote SQL fields' values:
$fields = '"' . join('", "', $values) . '"';
And for JavaScript use Array.join() method (W3C):
var implodedString = someArray.join(',')
if I get you right, you can use the implode function.
This does the job for you.
BR,
TJ
Why not:
echo implode(",", $list);
?
The common used practice: using 'join' function or its analog. This function exists almost in every language, so it's most simple, clear and environment independent approach.
echo join(", ", $list);

Object Oriented PHP Arrays

I've never tried OO PHP before so I decided to make a simple CMS to learn more. I am having a problem loading values into a multi-dimensional array.
class Article {
private $index = 0;
private $article;
public function Article() {
$get_articles = mysql_query("SELECT * FROM `articles`");
while ($result = mysql_fetch_array($get_articles)) {
echo $result["article"];
$this->article[$index]["Tags"] = $result["tags"];
$this->article[$index]["Categories"] = $result["categories"];
$this->article[$index]["Date"] = $result["date"];
$this->article[$index]["Article"] = $result["article"];
$this->article[$index]["URL"] = $result["url"];
$index++;
}
}
public function getArticle($articleID) {
return $this->article[$articleID]["Article"];
}
public function getTags($articleNumber) {
}
public function getCategories($articleNumber) {
}
public function getDate($articleNumber) {
}
}
The line echo $result["article"] outputs the one and only article value just fine, but apparently doesn't put it into the array?
$art = new Article();
echo $art->getArticle(0);
This doesn't output the article however. Would someone so kindly point out my noob mistake?
You didn't initialize your array.
$this->article = array();
while ($result = mysql_fetch_array($get_articles)) {
$this->article[$index] = array();
You probably should define your $index variable before using it in the loop. Maybe set it to the primary key field you retrieved from your query.
<?php
$index = $result['id'];
$this->article[$index]['tags'] = ...
You also need to initialize the $article member variable.
<?php
class Article {
private $article = array();
Remember that you define member variables within a class to be referenced via $this-> so you also don't need to define private $index = 0; in your class definition. Just define it inside the method.
You'll notice you used $this->article but not $this->index if you want to keep track of the length for the life of the object you'll need to replace $index with $this->index

Get PHP class property by string

How do I get a property in a PHP based on a string? I'll call it magic. So what is magic?
$obj->Name = 'something';
$get = $obj->Name;
would be like...
magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
Like this
<?php
$prop = 'Name';
echo $obj->$prop;
Or, if you have control over the class, implement the ArrayAccess interface and just do this
echo $obj['Name'];
If you want to access the property without creating an intermediate variable, use the {} notation:
$something = $object->{'something'};
That also allows you to build the property name in a loop for example:
for ($i = 0; $i < 5; $i++) {
$something = $object->{'something' . $i};
// ...
}
What you're asking about is called Variable Variables. All you need to do is store your string in a variable and access it like so:
$Class = 'MyCustomClass';
$Property = 'Name';
$List = array('Name');
$Object = new $Class();
// All of these will echo the same property
echo $Object->$Property; // Evaluates to $Object->Name
echo $Object->{$List[0]}; // Use if your variable is in an array
Something like this? Haven't tested it but should work fine.
function magic($obj, $var, $value = NULL)
{
if($value == NULL)
{
return $obj->$var;
}
else
{
$obj->$var = $value;
}
}
Just store the property name in a variable, and use the variable to access the property. Like this:
$name = 'Name';
$obj->$name = 'something';
$get = $obj->$name;
There might be answers to this question, but you may want to see these migrations to PHP 7
source: php.net
It is simple, $obj->{$obj->Name} the curly brackets will wrap the property much like a variable variable.
This was a top search. But did not resolve my question, which was using $this. In the case of my circumstance using the curly bracket also helped...
example with Code Igniter get instance
in an sourced library class called something with a parent class instance
$this->someClass='something';
$this->someID=34;
the library class needing to source from another class also with the parents instance
echo $this->CI->{$this->someClass}->{$this->someID};
Just as an addition:
This way you can access properties with names that would be otherwise unusable$x = new StdClass;
$prop = 'a b';
$x->$prop = 1;
$x->{'x y'} = 2;
var_dump($x);object(stdClass)#1 (2) {
["a b"]=>
int(1)
["x y"]=>
int(2)
}(not that you should, but in case you have to).
If you want to do even fancier stuff you should look into reflection
In case anyone else wants to find a deep property of unknown depth, I came up with the below without needing to loop through all known properties of all children.
For example, to find $foo->Bar->baz->bam, given an object ($foo) and a string like "Bar->baz->bam".
trait PropertyGetter {
public function getProperty($pathString, $delimiter = '->') {
//split the string into an array
$pathArray = explode($delimiter, $pathString);
//get the first and last of the array
$first = array_shift($pathArray);
$last = array_pop($pathArray);
//if the array is now empty, we can access simply without a loop
if(count($pathArray) == 0){
return $this->{$first}->{$last};
}
//we need to go deeper
//$tmp = $this->Foo
$tmp = $this->{$first};
foreach($pathArray as $deeper) {
//re-assign $tmp to be the next level of the object
// $tmp = $Foo->Bar --- then $tmp = $tmp->baz
$tmp = $tmp->{$deeper};
}
//now we are at the level we need to be and can access the property
return $tmp->{$last};
}
}
And then call with something like:
$foo = new SomeClass(); // this class imports PropertyGetter trait
echo $foo->getProperty("bar->baz->bam");
Here is my attempt. It has some common 'stupidity' checks built in, making sure you don't try to set or get a member which isn't available.
You could move those 'property_exists' checks to __set and __get respectively and call them directly within magic().
<?php
class Foo {
public $Name;
public function magic($member, $value = NULL) {
if ($value != NULL) {
if (!property_exists($this, $member)) {
trigger_error('Undefined property via magic(): ' .
$member, E_USER_ERROR);
return NULL;
}
$this->$member = $value;
} else {
if (!property_exists($this, $member)) {
trigger_error('Undefined property via magic(): ' .
$member, E_USER_ERROR);
return NULL;
}
return $this->$member;
}
}
};
$f = new Foo();
$f->magic("Name", "Something");
echo $f->magic("Name") , "\n";
// error
$f->magic("Fame", "Something");
echo $f->magic("Fame") , "\n";
?>
What this function does is it checks if the property exist on this class of any of his child's, and if so it gets the value otherwise it returns null.
So now the properties are optional and dynamic.
/**
* check if property is defined on this class or any of it's childes and return it
*
* #param $property
*
* #return bool
*/
private function getIfExist($property)
{
$value = null;
$propertiesArray = get_object_vars($this);
if(array_has($propertiesArray, $property)){
$value = $propertiesArray[$property];
}
return $value;
}
Usage:
const CONFIG_FILE_PATH_PROPERTY = 'configFilePath';
$configFilePath = $this->getIfExist(self::CONFIG_FILE_PATH_PROPERTY);
$classname = "myclass";
$obj = new $classname($params);
$variable_name = "my_member_variable";
$val = $obj->$variable_name; //do care about the level(private,public,protected)
$func_name = "myFunction";
$val = $obj->$func_name($parameters);
why edit:
before : using eval (evil)
after : no eval at all. being old in this language.

Categories