Define data members within constructor - php

I have got this little snippet of code, I want to be able to define each array element as a new data member.
class Core_User
{
protected $data_members = array(
'id' => '%d',
'email' => '"%s"',
'password' => '"%s"',
'title' => '"%s"',
'first_name' => '"%s"',
'last_name' => '"%s"',
'time_added' => '%d' ,
'time_modified' => '%d' ,
);
function __construct($id = 0, $data = NULL)
{
foreach($this->data_members as $member){
//protected new data member
}
}

//protected new data member
You won't be able to create a non-public property at runtime. If protected is paramount, you can declare a protected array or object and insert key/values into it in the constructor

Always use $this when you want to access object's members (it should be $this->data_members in constructor).
You can try defining magic methods __get & __set (I'm not sure if they can be protected though). :
protected function __get($name){
if (array_key_exists($name,$this->data_memebers))
{
return $this->data_memebers[$name];
}
throw new Exception("key $name doesn't not exist");
}
protected function __set($name,$value){
if (array_key_exists($name,$this->data_memebers))
{
$this->data_memebers[$name] = $value;
}
throw new Exception("key $name doesn't not exist");
}

What you want to achieve is possible, however you won't be able to make the new properties protected (as this is only possible for predefined members).
function __construct($id = 0, $data = NULL)
{
foreach($this->$data_memebers as $name => $value ){
$this->$name = $value;
}
}
Note the use of the $ before name in $this->$name: This makes PHP use the current value of the $name variable as property.

Related

php add method from object class to another object class

i have a object like this:
CORE::$ObjClassInstABS['ABS']['DATA']
that contains an array of Class->Method:
array (
'DATA' =>
array (
'USERDATAMANAGER' =>
Class_UserdataManager::__set_state(array(
)),
'PRODDATAMANAGER' =>
Class_ProddataManager::__set_state(array(
)),
),
)
i create a new object, of type class Like this:
CORE::$ObjClassInstABS['ABS']['ABSDATAMANAGER'] = new class;
i cant but need pass all the methods of the first object, ignoring the class of origin to the class i create on fly, and that allows me to execute the functions from the class declared on the fly.
does this exist in php 7.0 or is there any way to achieve this reach??
It would be like cloning the methods of several classes to a single and new class.
Answer for #Damian Dziaduch comments
the piece of code that i used to Dynamically Instance all class file from a directory is this, and populate the first object with instance of class:
CORE::$ObjClassInstABS['ABS']['ABSDATAMANAGER']= new class;
foreach (CORE::$ObjClassABS['DATA'] as $key => $name) {
if (strpos($name, 'class.') !== false) {
$name = basename($name);
$name = preg_replace('#\.php#', '', $name);
$names = explode(".", $name);
foreach ($names as $key => $namesr) {
$names[$key] = ucfirst(strtolower($namesr));
}
$name = implode('_', $names);
$NamesClass = $name . 'Manager';
$InstanceClass = strtoupper(preg_replace('#\Class_#', '', $NamesClass));
CORE::$ObjClassInstABS['ABS']['DATA'][$InstanceClass] = $this->$InstanceClass = new $NamesClass();
}
}
the result of it is the Array printed at start of the post CORE::$ObjClassInstABS['ABS']['DATA'] .
if you see at start of foreach i have the new class declaration to use, in loop, how can i populate CORE::$ObjClassInstABS['ABS']['ABSDATAMANAGER'] in the loop, it with all methods of the first object instance, and make it executables?
that i whant (not work):
foreach ( CORE::$ObjClassInstABS['ABS']['DATA'] as $key => $value ) {
CORE::$ObjClassInstABS['ABS']['ABSDATAMANAGER'] .= Clone($value);
}
$value represent where is storing the methods:
::__set_state(array()),
As requested.
Not sure whether this will fill you requirements... The question is whether you are able to overwrite the CORE::$ObjClassInstABS
<?php
CORE::$ObjClassInstABS = new class extends \ArrayIterator {
private $container = [];
public function __construct(array $container)
{
$this->container = [
'ABS' => [
'DATA' => [
'USERDATAMANAGER' => new class {},
'PRODDATAMANAGER' => new class {},
],
],
];
}
public function offsetExists($offset)
{
return isset($this->container[$offset]);
}
public function offsetGet($offset)
{
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
public function offsetSet($offset, $value)
{
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetUnset($offset)
{
unset($this->container[$offset]);
}
};

Undefined variable answers eventhough variable is defined

<?php
class Question_model extends CI_Model {
public $answers;
public function filter_answers($value){
if(is_string($value))
{
if(strpos($value,"option") !== false){
$this->$answers[] = str_replace("option","",$value);
}
}
}
public function create_question($data){
$data = array(
'explanation' => $data['exp'],
'name' => $data['name']
);
$this->db->insert('question', $data);
array_filter($data,array($this,"filter_answers"));
echo $this->$answers;
}
}
I am using codeigniter framework and i am getting this in model as you can see that variable is actually defined and not the other way around. I am calling model from codeigniter controller.
You must be call answer property with $this->answers, not by $this->$answers.
<?php
class Question_model extends CI_Model {
public $answers;
public function filter_answers($value){
if(is_string($value))
{
if(strpos($value,"option") !== false){
$this->answers[] = str_replace("option","",$value);
}
}
}
public function create_question($data){
$data = array(
'explanation' => $data['exp'],
'name' => $data['name']
);
$this->db->insert('question', $data);
array_filter($data,array($this,"filter_answers"));
echo $this->answers;
}
}
The double arrow operator, “=>”, is used as an access mechanism for
arrays. This means that what is on the left side of it will have a
corresponding value of what is on the right side of it in array
context. This can be used to set values of any acceptable type into a
corresponding index of an array. The index can be associative (string
based) or numeric.
<?php
$myArray = array(
0 => 'Big',
1 => 'Small',
2 => 'Up',
3 => 'Down'
);
?>
The object operator, “->”, is used in object scope to access methods
and properties of an object. It’s meaning is to say that what is on
the right of the operator is a member of the object instantiated into
the variable on the left side of the operator. Instantiated is the key
term here.
<?php
$obj = new MyObject(); // Create a new instance of MyObject into $obj
$obj->thisProperty = 'Fred'; // Set a property in the $obj object called thisProperty
$obj->getProperty(); // Call a method of the $obj object named getProperty
?>
Example
<?php
class Question_model extends CI_Model {
public $answers;
public function filter_answers($value){
if(is_string($value))
{
if(strpos($value,"option") !== false){
$this->answers[] = str_replace("option","",$value);
}
}
}
public function create_question($data){
$data = array(
'explanation' => $data['exp'],
'name' => $data['name']
);
$this->db->insert('question', $data);
array_filter($data,array($this,"filter_answers"));
echo $this->answers;
}
}

serialize and unserialize functions

I know serialization is the process of taking a complicated object and reducing it down to zeros and ones for either storage or transmission. But I'm confused about the interface Serializable
For example, we have colde like
class Artist implements Serializable {
public function serialize() {
return serialize(
array("earliest" =>self::$earliestDate,
"first" => $this->firstName,
"last" => $this->lastName,
"bdate" => $this->birthDate,
"ddate" => $this->deathDate,
"bcity" => $this->birthCity,
"works" => $this->artworks
);
);
}
public function unserialize($data) {
$data = unserialize($data);
self::$earliestDate = $data['earliest'];
$this->firstName = $data['first'];
$this->lastName = $data['last'];
$this->birthDate = $data['bdate'];
$this->deathDate = $data['ddate'];
$this->birthCity = $data['bcity'];
$this->artworks = $data['works'];
}
//...
}
For example, unserialize($data)is the method that we implements, but how come it call itself inside the function like "$data = unserialize($data)",isn't it a infinite loop? Is the inside function unserialize($data) the same one as outside unserialize($data) function?

How to automatically apply values to class variables in PHP without using try/catch [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
PHP - Initialize object members with array parameter
I am looking for a way to have my class apply data from an associative array to its own member variables. However, if those variables do not exist, the process should not throw any errors.
Please note: i am either not looking for what the extract() function does or i misunderstand its behaviour.
Example:
class customer {
public $firstName;
public $lastName;
public $email;
public function apply($data){
/* here i want to be able to iterate through $data and set the class
variables according to the keys, but without causing problems
(and without creating the variable in the class) if it does not exist
(yet)) */
}
}
$c=new customer();
$c->apply(array(
'firstName' => 'Max',
'lastName' => 'Earthman',
'email' => 'max#earthman.com'
));
Hope the description is proper.
Please ask if anything is unclear.
You can do something like this
class customer {
public $firstName;
public $lastName;
public $email;
public function apply($data) {
$var = get_class_vars(__CLASS__);
foreach ( $data as $key => $value ) {
if (array_key_exists($key, $var)) {
$this->$key = $value;
}
}
}
}
$c = new customer();
$c->apply(array('firstName' => 'Max','lastName' => 'Earthman','email' => 'max#earthman.com',"aaa" => "bbb"));
var_dump($c);
Output
object(customer)[1]
public 'firstName' => string 'Max' (length=3)
public 'lastName' => string 'Earthman' (length=8)
public 'email' => string 'max#earthman.com' (length=16)
//Works for private as of 5.3.0
//Will also return statics though.
public function apply($data){
foreach($data as $key => $val) {
if(property_exists('customer',$key)) {
$this->$key = $val;
}
}
}
If this is coming from a database there are functions to return the object directly rather than having to apply the associated array to a class. Just a thought.

Why is my getter magic method using a class instance as an index?

here's my getter:
public function __get($field)
{
if ($field == 'userId'):
return $this->uid;
else:
return $this->fields[$field];
endif;
}
here's my constructor
public function __construct()
{
$this->uid = null;
$this->fields = array(
'username' => '',
'password' => '',
'firstname' => '',
'lastname' => '',
'email' => '',
'is_active' => false
);
$this->session = Session::Instance();
$this->profiler = new Profiler();
$this->encrypt = new Encrypt();
}
everytime i access this function:
private function handle_pass($password, $username=null, $encrypt=true)
{
if ($encrypt) :
return $this->encrypt->encode($password);
else:
$query = ORM::factory('user');
$result = $query
->select('password')
->where('username', $username)
->find();
$compare_pass = $this->encrypt->decode($password);
return ($compare_pass === $result->password);
endif;
}
i get this error
application/libraries/User.php: Undefined index: encrypt // this is the error message
application/libraries/User.php:User->__get( encrypt ) // this is the last method executed
Is encrypt defined as a public variable in the class? If not, the logic of your __get() function demands that it be read from $this->fields['encrypt'], which is never set, and is what's producing that error.
Use get_object_vars on the object before attempting to access the encrypt property to see if it really exists. Something else could be going on.
var_dump(get_object_vars($myClass));
Edit:
After looking at your code. The get() method should never be called since it is only invoked when a referenced property is inaccessible. Are you declaring $encrypt as private? Are you declaring it at all? What makes you think get() should be invoked? (Formatter goes crazy when I try to put underscores infront of get() with a link).
class myClass()
{
public $encrypt;
public function __construct()
{
$this->encrypt = new Encrypt();
}
public function __get($property)
{
return $this->$property;
}
public function handle_pass()
{
$this->encrypt->decode();
// Since $encrypt is public, __get() will not be invoked
}
}

Categories