declare field without initial value in php? - php

I don't want to give an initial value. I want to set these later using the set method
class Duck {
var int id;
var set = Array();
}
Any idea how to declare without getting error?

Your question is marked PHP but it doesn't look like any PHP I know. This is correct PHP:
class Duck {
private $id;
private $set = array();
}
You don't need to specify an initial value for $set as in this example but that just means it gets the standard default value of 0, false, array(), etc depending on how it's used so I'm not sure what you're trying to achieve.
You're typically better off being explicit.

class Duck { var $int, $set = array(); }

Much more PHP is:
class Duck {
public $id;
}
$d = new Duck;
$d->id = 5;

A method could be Typ checking;
private $props = array();
static $types = array ("id" => "is_integer","name" => "is_string");
public function __set($name,$value)
{
if(array_key_exists($name, self::$types))
{
if(call_user_func(self::$types[$name],$value))
{
$this->props[$name] = $value;
}
else
{
print "Type assignment error\n";
debug_print_backtrace();
}
}
}

Related

php declare public variable inside function

I want to declare a variable inside a class with an unknown name
class Example {
function newVar($name, $value) {
$this->$name = $value;
}
}
And I want to use it that way
$c = new Example();
$c->newVar('MyVariableName', "This is my Value");
echo($c->MyVariableName);
The Important thing is, that I do not know the name of the variable. So I cannot put a public $MyVariable inside the class.
Is that in anyway possible? and if yes, can i do this with different scopes (private, protected, public) ?
U should use magic methods __get and __set (example without checking):
class Example {
private $data = [];
function newVar($name, $value) {
$this->data[$name] = $value;
}
public function __get($property) {
return $this->data[$property];
}
public function __set($property, $value) {
$this->data[$property] = $value;
}
}
$c = new Example();
$c->newVar('MyVariableName', "This is my Value");
echo($c->MyVariableName);
// This is my Value
$c->MyVariableName = "New value";
echo($c->MyVariableName);
// New value
See http://php.net/manual/en/language.oop5.magic.php
If i am understanding this correctly you can tweak a little bit by using key value array
class Example {
private $temp;
function __construct(){
$this->temp = array();
}
function newVar($name, $value) {
$this->temp[$name] = $value;
}
function getVar($name){
return $this->temp[$name];
}
}
$c = new Example();
$c->newVar('MyVariableName', "This is my Value");
echo($c->getVar('MyVariableName'));
Instead of using private you can use protected as well.
Your looking for magic calling. In PHP you can use the __call() function to do stuff like that. Have a look here: http://www.garfieldtech.com/blog/magical-php-call
Off the top of my head, something like
function __call($vari, $args){
if(isset($this->$vari){
$return = $this->$vari;
}else{
$return = "Nothing set with that name";
}
}
This will also work for private, protected and public. Can also use it to call methods as required in a class

$this->"variable value" OOP PHP

I'm wondering if it's possible, and in case it is, how shoud I achive that:
$this->id <-- i have such thing. but to make it more usable i'd like to have $this->(and here to change the values)
for ex: I might have $this->id $this->allID $this->proj_id
how can I make so that actually I have $this->($myvariable here, that has a unique name in it)?
You can simply use this:
$variable = 'id';
if ( isset ( $this->{$variable} ) )
{
echo $this->{$variable};
}
Here is the solution : http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members
An example of using it is here :
class myClass {
/** Location for overloaded data. */
private $myProperties = array();
public function __set($name, $value)
{
$this->myProperties[$name] = $value;
}
public function __get($name)
{
if (array_key_exists($name, $this->myProperties))
{
return $this->data[$name];
}
}
}
You should check out the variable variables manual on the PHP site.
With that, it could look like:
<?php
echo ${'this->'.$yourvariable};
?>
I prefer to use call_user_func and pass the parameters as array instead.
public function dynamicGetterExample()
{
$property = 'name'; // as an example...
$getter = 'get'.ucfirst($property);
$value = call_user_func(array($this,$getter));
if (empty($value)) {
throw new \Exception('Required value is empty for property '.$property);
}
return $value;
}

pass variable as an array

Hi in my user class i am passing the variables in constructor instead of passing variables i want to pass as an array.
Class User{
var $userid;
var $alias;
var $firstname;
var $password;
var $email;
var $photo;
var $avatar_url;
var $thumb;
var $crop_url;
var $crop_position;
protected $db;
function User($userid='',$alias='',$firstname='',$lastname='',$password='',$email='',$photo='',$avatar_url='',$thumb='',$crop_url='',$crop_position='',PDO $db){
$this->userid=$userid;
$this->alias= $alias;
$this->firstname=$firstname;
$this->lastname=$lastname;
$this->password= $password;
$this->email=$email;
$this->photo= $photo;
$this->avatar_url= $avatar_url;
$this->thumb= $thumb;
$this->crop_url= $crop_url;
$this->crop_position= $crop_position;
$this->db = $db;
}
}
and the variable coming in constructor
$user=new User($id,$alias,$firstname,$lastname,$password,$email,$photo='',$avatar_url='',$thumb='',$crop_url='',$crop_position='',$db);
this all are coming through the request variable.
Please help.Thanks
You didn't clarify what your issue is. If you want to pass an array, then pass an array. If you cannot change your API for the ctor for BC reasons, you can add another method to your User class, e.g.
class User
{
// other code …
public function populateFromArray(array $data)
{
foreach ($data as $property => $value) {
if (property_exists($this, $property)) {
$user->$property = $value;
}
}
}
}
Then you can do
$user = new User('','','','','','','','','','','',$db);
$user->populateFromArray(array(
'id' => 'johndoe',
'email' => 'jdoe#example.com',
// other …
));
The ctor call looks pretty ugly, so if you can afford to change the API, I suggest to move required arguments to the beginning of the signature. This is suggested good practise in the PHP Manual anyway, e.g. change your ctor to
public function __construct(PDO $pdo, $id = '', $email = '', …) {
Note that I changed it to the new PHP5 style constructor. Naming the ctor after the class name is PHP4 style and is not compatible with namespaces as of PHP5.3.3.. You might also want to change your var keyword to public (or better yet protected and add proper getter and setter).
Since everything but the PDO instance is optional, you can just as well remove all the optional arguments and always use your new populateFromArray method instead, reducing the instantiation to
$user = new User($db);
$user->populateFromArray($dataArray);
If you want to implement the populateFromArray functionality in other classes as well, you might want to consider adding an interface IPopulate, e.g.
interface IPopulate
{
public function populateFromArray(array $data);
}
But your classes implementing this interface would have to add the method body each time, which is a bit redundant given that our populating code is quite generic. With php.next there will be traits for an elegant solution for horizontal reuse like this.
Yet another possible solution would be to just use the Reflection API to pass the array to your regular ctor (though you should give it a benchmark afterwards because the Reflection API is considered slow). See
Pass arguments from array in php to constructor
User.php Class:
// define your default values here. so that you will not have to pass them
// everytime when you pass the array to `AssignVal` function.
Class User{
var $userid = '';
var $alias = '';
var $firstname = '';
var $password = '';
var $email = '';
var $photo = '';
var $avatar_url = '';
var $thumb = '';
var $crop_url = '';
var $crop_position = '';
protected $db;
function User(PDO $db) {
$this->db = $db;
}
}
Index.php (where you want the object to be created):
$user = assignVal('User',$arr);
functions.php (a place where you include all your functions):
// the following function creates an object with the array you send it.
// this is specially useful if your class contains a lot of variables
// thus minimizing the manual work of defining constructors again and again...
function assignVal($obj,$arr,$child=null) {
if (is_string($obj)) $obj = new $obj();
$applyon = $child == null ? $obj : $obj->$child;
if(!empty($arr)) {
foreach ($arr as $name => $val) {
$applyon->$name = $val;
}
}
if ($child != null) $obj->$child = $applyon;
else $obj = $applyon;
return $obj;
}
First create your array:
$Usr_info = array('id' => 0, 'alias' => 'value'); //add all the values you want like that
And then in your constructor you can access each item in the array:
function User($Usr_info)
{
$this->userid = $Usr_info['id'];
//and so on...
}
version for PHP5
class User {
private $userid;
...
public function assign ($class_member, $value) {
$this->$class_member = $value;
}
public function __construct ($db) {
$this->db = $db;
}
}
...
$user = new User($db);
$user->assign('userid', 1);

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