Add dynamic varible to form/model in Yii - php

Please help, how i can add dynamic varible in Yii CFormModel?
private function magic($name, $value) {
$this->$name = $value;
}
or
$form = new FormGenerate($attributes);
$form->temp = '1';
Show me Exception "Undetermined property" =(

In your class try something like this
class Test
{
public function __construct($x)
{
$this->{$x} = "dynamic";
}
}
$a = new Test("bar");
print $a->bar;
try changing your
$this->$name
to
$this->{$name}
to see what happens.

I create varible $_params;
And
public function __get($name)
{
if (isset($this->_params[$name])) {
return $this->_params[$name];
}
return parent::__get($name);
}
public function __set($name, $value)
{
if (isset($this->_params[$name])) {
$this->_params[$name] = $value;
} else {
parent::__set($name, $value);
}
}
It's work =)

Related

Creating staitic method and calling the method in PHP

I'm getting value form Form class by creating object.It's working fine.But I wanna do it using static method.I tried but did not succeed.
public function display()
{
$newform=new Form();
echo "<pre>";
var_dump($newform->getAll());
var_dump($newform->get('name'));
}
<?php
class Form
{
private $value = array();
function __construct() {
// here you can use some validation or escapes
foreach($_POST as $key=>$value)
$this->value[$key] = $value;
}
public function getAll() {
return $this->value;
}
public function get($value) {
$this->value = $_POST[$value];
return $this->value;
}
}
Maybe You should just try to read PHP documentation about static keyword?
Example:
class Form {
private static $value = array();
public static function factory() {
// here you can use some validation or escapes
foreach($_POST as $key => $value) {
static::$value[$key] = $value;
}
}
public static function getAll() {
return static::$value;
}
public static function get($key) {
return static::$value[$key];
}
}
Use:
public function display() {
Form::factory();
echo "<pre>";
var_dump(Form::getAll());
var_dump(Form::get('name'));
echo "</pre>";
}
you do not declare a function as public/private/protected outside of the class
you you want to call this method statically, you may try it
<?php
function display()
{
$newform=new Form($_POST);
echo "<pre>";
var_dump(Form::getAll());
var_dump(Form::get('name'));
}
class Form
{
private static $value = array();
function __construct(){
// here you can use some validation or escapes
function __constract($array){
foreach($array as $key=>$value)
self::$value[$key] = $value;
}
}
public static function getAll(){
return self::$value;
}
public static function get($value){
self::$value = self::$value[$value];
return self::$value;
}
}
Here is an example for getAll method. For get method the same idea:
public function display()
{
var_dump(Form::getAll());
}
class Form
{
private static $value = array();
public static function initPost()
{
foreach($_POST as $key=>$value)
self::$value[$key] = $value;
}
public static function getAll()
{
return self::$value;
}
}

Running class methods in cascade

I have a system that was designed to do a kind of cascading - get the sequence of methods called upon success of the previous condition.
The example is the below code, which I presume it's not a best practice for doing this, so would be great if I could get some suggestions to refactor this, probably using a design pattern or a different than this system.
<?php
class Model
{
public function isOk()
{
return true;
}
}
class OtherClass
{
public function isOk()
{
return true;
}
}
class AnotherClass
{
public function verifies()
{
return true;
}
}
class Sequence
{
public function fire()
{
$model = new Model();
if($model->isOk()) {
$otherclass = new OtherClass();
if($otherclass->isOk()) {
$anotherclass = new AnotherClass();
if($anotherclass->verifies()) {
echo "We're done with the sequence.";
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
}
$sequence = new Sequence();
echo $sequence->fire();
?>
I would avoid deep nesting of if/else statements to enhance the readability. One way is to use early return:
class Test1
{
public function isOk()
{
echo 'Test1';
return true;
}
}
class Test2
{
public function isOk()
{
echo 'Test2';
return true;
}
}
class Sequence
{
public function fire()
{
$test1 = new Test1();
if (!$test1->isOk()) {
return false;
}
$test2 = new Test2();
if (!$test2->isOk()) {
return false;
}
echo "We're done with the sequence.";
return true;
}
}
If you need it more dynamically you could use call_user_func or call_user_func_array.
class Sequence
{
protected $sequence = array(
array('Test1', 'isOk'),
array('Test2', 'isOk'),
);
public function fire()
{
foreach ($this->sequence as $callback) {
if (!call_user_func(array(new $callback[0], $callback[1]))) {
return false;
}
}
echo "We're done with the sequence.";
return true;
}
}

Special class value in PHP

Some code:
class MyClass
{
public function __get($key)
{
return $this[$key];
}
public function __set($key, $value)
{
$this[$key] = $value;
}
}
$m = new MyClass();
$m->name = 'This is my class.';
OR
$m['name'] = 'This is my class.';
But not working. Somebody can help me?
In order to be able to access values in your class using array access, you have to implement the ArrayAccess interface. In order to also arbitrary property names dynamically, copy the sample code from that page. Once you've implemented the ArrayAccess methods your __get and __set will work as-is.
<?php
class obj implements arrayaccess {
private $container = array();
public function __construct() {
$this->container = array(
"one" => 1,
"two" => 2,
"three" => 3,
);
}
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetExists($offset) {
return isset($this->container[$offset]);
}
public function offsetUnset($offset) {
unset($this->container[$offset]);
}
public function offsetGet($offset) {
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
public function __get($key) {
return $this[$key];
}
public function __set($key, $value) {
$this[$key] = $value;
}
}
$foo = new obj();
$foo->pill = 123;
var_dump($foo->pill);
The problem you are having is that inside the __get and __set methods, you are accessing the properties as an array. You need to use $this->$key instead of $this[$key].
class MyClass
{
public function __get($key)
{
return $this->$key;
}
public function __set($key, $value)
{
$this->$key = $value;
}
}
$m = new MyClass();
echo "before set: \n";
var_dump($m);
$m->foo = "bar";
echo "after set: \n";
var_dump($m);
Example: http://codepad.viper-7.com/oNLbzq
Try this approach
class MyClass
{
private $m_var_data = array();
public function __set($p_name, $p_value)
{
$this->m_var_data[$p_name] = $p_value;
}
public function __get($p_name)
{
if (array_key_exists($p_name, $this->m_var_data))
{
return $this->m_var_data[$p_name];
}
}
}
$m = new MyClass();
$m->name = 'This is my class.';
In order to create a new property, you should do this:
class MyClass
{
private $data = array();
public function __set($name, $value)
{
echo "Setting '$name' to '$value'\n";
$this->data[$name] = $value;
}
public function __get($name)
{
echo "Getting '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
}
}
Then you can overload properties as you want in your example.
This link can give you more references:
http://www.php.net/manual/pt_BR/language.oop5.overloading.php#language.oop5.overloading.members

Place _construct inside a if()

Is there a way to :
class foo {
private $skey;
if(isset($_SESSION['some_val']) {
function __construct(){
$skey = 'something';
}
}
}
I just want to create the initial value of $key (something), if the $_SESSION['some_val'] doesn't exist.
Thanks in advance
edit:
this is what I did with your help
function __construct() {
if(!isset($_SESSION['skey'])) {
$tp = new Text_Password();
$skey = $tp->create();
$this->skey = $skey;
$_SESSION['skey'] = $this->skey;
}
}
Nope. However, you can simply do this:
class foo {
function __construct()
{
if(isset($_SESSION['some_val'])
{
$this->key = 'something';
}
}
}
No, that's impossible. You could do this:
class foo {
private $key;
function __construct(){
if (isset($_SESSION['some_val']) {
$this->key = 'something';
} else {
$this->key = null;
}
}
}
Or better, use a parametrised constructor and leave the $_SESSION stuff in you main application:
class foo {
private $key;
function __construct($init = null){
$this->key = $init;
}
}
Then in your main app:
if (isset($_SESSION['some_val'])) {
$f = new foo('something');
} else {
$f = new foo();
}
You should just put inside the construct method.
class foo {
private $key;
public function __construct(){
if(isset($_SESSION['some_val']) {
$this->key = 'something';
}
}
}

Is it possible to make a names of the tables in the database as a methods of my class?

I am very like to use PDO, so it might be on.
Usage could be as:
$m = new MDB();
$m->Users()->GetRec($param);
Users() is a name of table in the database, GetRec($param) is my function.
A way I go looking like this:
class MDB extends DB {
function __construct(){
parent::__construct();
if ($result = $this->pdo->query("SHOW TABLES"))
{
while ($row = $result->fetch(PDO::FETCH_NUM))
{
// this is only my imagination (not working at all)
__set($row[0],true);
}
}
}
// set
public function __set($name, $value)
{
// here could be a method (not properties)
$this->$name = $value;
}
Sure it's all seems not exactly what I want. So I am able to get some suggestions and advices in this question.
upd 1.
Thanks for the magic method __call and now I'm trying to make it within. Watch my updated code:
class MDB extends DB {
function __construct(){
parent::__construct();
}
public function __call( $method, $param )
{
$tables = array();
if ($result = $this->pdo->query("SHOW TABLES"))
{
while ($row = $result->fetch(PDO::FETCH_NUM))
{
$tables[] = $row[0];
}
}
if (in_array($method,$tables))
{
return $this;
}
else
{
return FALSE;
}
}
Well, seems it works for me!
Yes it's possible! The wrong row in your code is:
__set($row[0],true);
There you should call:
$this->$row[0] = true;
Take a look a the simple example below and at the overloading documentation of PHP http://www.php.net/manual/en/language.oop5.overloading.php.
class A{
//The array which will contain your data
private $tables;
function __construct($array){
$counter = 1;
foreach($array as $value){
//That's the right call!
$this->$value = $counter++;
}
}
function __set($name, $value){
$this->tables[$name] = $value;
}
function __get($name){
if (array_key_exists($name, $this->tables)) {
return $this->tables[$name];
}
}
}
$array = array('a1', 'a2', 'a3', 'a4', 'a5');
$a = new A($array);
foreach($array as $key){
echo $a->$key;
}
Hope this help!

Categories