How can I change existing function in a class - php

I have a form class and I want define different functions when form be submitted.
<?php
class Forms {
function __construct() {
if (!empty($_POST['exampleInput'])) {
$this->PostedForms();
}
}
function __call($func, $param) {
}
function PostedForms() {
if (!empty($_POST['exampleInput'])) {
if (function_exists($this->userDefined)) {
$this->userDefined();
}
}
}
}
$form = new Forms();
$form->userDefined = function ($param) {
print_r($_POST);
}
?>
I want define userDefined function outside of class. How can I do this? Can I change any function of class after class was called? Can I change userDefined = function ($param) {print_r($_GET);} for example?

Related

Yii function in layout file

I'm using Yii and I'm new to it.
I have a default main.php layout file and i need to make some data extractions from DB and cookies.
I've written 2 functions:
public function getRegionId() {
if(isset(Yii::app()->request->cookies['region_id'])) {
$sk = Yii::app()->request->cookies['region_id']->value;
settype($sk,integer);
return $sk;
} else {
return 1;
}
}
public function regionId2region($id) {
if(empty($id) or gettype($id)!=='integer') {
return null;
} else {
$reg = Regions::model()->findAll(array(
'condition'=>"alive=1 AND id=".$id,
));
return $reg;
}
}
Now it is not working in any controller. My question is: is it possible to make functions in the layout file or is there a way to pass data to layout file (so that it displays in all controllers)?
Move methods into Regions model and make it static. Or Create Helper class? contains just static methods.
class RegionHelper {
public static function getRegionId() {
if(isset(Yii::app()->request->cookies['region_id'])) {
return (int)$Yii::app()->request->cookies['region_id']->value;
}
return 1;
}
public static function regionId2region($id) {
if(empty($id) or gettype($id)!=='integer') {
return null;
} else {
$reg = Regions::model()->findAll(array(
'condition'=>"alive=1 AND id=".$id,
));
return $reg;
}
}
}
You can use BeforeAction in your controller, like this:
protected function beforeAction($action) {
//Define your variable here:
public $yourVaribale;
//do your logic and assign any value to variable
}
Now, you can use this variable in the view file:
view:
<h1><?php echo $this->yourVariable; ?></h1>
If your functions are located in the controller that calls the view, you could use the $this reference to access the function. Note the public access of the function.
class UserController extends Controller
{
// :
// :
public function fullName($a,$b) {
return $a.' '.$b;
}
}
...and in your view ...
<h1>Test for <?php echo $this->fullName('Tom', 'Jones'); ?></h1>
If the function is in your model, there are a few choices.
class User extends Activerecord
{
// :
// :
public function fullName($a,$b) {
return $a.' '.$b;
}
}
You could pass the model through the render function,
class UserController extends Controller
{
// :
// :
public function actionDisplayView {
$userModel = User::model()->findByPK(1);
$this->render('user_view', array('model' => $model));
}
}
and directly call the function in the view.
< h1 >Test for <?php echo $model->fullName('Tom', 'Jones'); ?>< / h1 >
or, if you did not pass the function, you could call the function in the view (or helper classes). Watch the scope.
class User extends Activerecord
{
// :
// :
// NOTE: You won't have access to $this.
static public function fullName($a,$b) {
return $a.' '.$b;
}
}
and in the view
< h1 >Test for <?php echo User::fullName('Tom', 'Jones'); ?>< /h1 >

php class function wrapper

this is my class:
class toyota extends car {
function drive() {
}
function break() {
}
}
class car {
function pre() {
}
}
Is there any way I can do so that when I run $car->drive(), $car->break() (or any other function in toyota), it would call $car->pre() first before calling the functions in toyota?
Yep. You could use protected and some __call magic:
class toyota extends car {
protected function drive() {
echo "drive\n";
}
protected function dobreak() {
echo "break\n";
}
}
class car {
public function __call($name, $args)
{
if (method_exists($this, $name)) {
$this->pre();
return call_user_func_array(array($this, $name), $args);
}
}
function pre() {
echo "pre\n";
}
}
$car = new toyota();
$car->drive();
$car->dobreak();
http://ideone.com/SGi1g
You could do the following, but I don't think that is what you want.
class toyota extends car {
function drive() {
$this->pre();
}
function break() {
$this->pre();
}
}
class car {
function pre() {
}
}
You may want to look into PHP specific magic methods. http://php.net/manual/en/language.oop5.magic.php
This will better done with the magic methods called __call()
public function __call($name, $arguments)
{
$this -> pre();
return $this -> $name($arguments);
}
What is this method? It overrides the default method call, so that preCall State can be invoked.
Your toyota class
class toyota extends car {
public function __call($name, $arguments)
{
$this -> pre();
return call_user_func_array(array($this, $name), $arguments);
}
function drive() {
}
function break() {
}
}
If you are using PHP5 (>=5.3.2), there is a solution that works with declaring all methods as private. This will enforce method call from single function call:
exec_method()
To run at: http://ideone.com/cvfCXm
The code snippet is here:
<?php
class car {
//method to get class method
public function get_method($method_name) {
$class = new ReflectionClass(get_class($this));
$method = $class->getMethod($method_name);
$method->setAccessible(true);
return $method;
}
public function exec_method($method_name, $arg_args=array()) {
//execute the pre() function before the specified method
$this->pre();
//execute the specified method
$this->get_method($method_name)->invokeArgs($this, $arg_args);
}
public function pre() {
echo 'pre';
echo '<br />';
}
}
class toyota extends car {
private function drive() {
echo 'drive';
echo '<br />';
}
private function brake() {
echo 'brake';
echo '<br />';
}
}
$toyota = new toyota();
$toyota->exec_method('drive');
$toyota->exec_method('brake');
?>
Reference:
Answer to Best practices to test protected methods with PHPUnit [closed]
Just add a constructor, like this...
class toyota extends car {
function __construct() {
$this->pre();
}
function drive() {
echo "drive!";
}
function dobreak() {
echo "break!";
}
}
class car {
function pre() {
echo "Hello!";
}
}
$car = new toyota();
$car->drive();
$car->dobreak();
Classes which have a constructor method call this method on each
newly-created object, so it is suitable for any initialization that
the object may need before it is used.
break is reserved, so you shouldn't use this as a function name.

Default class for form elements

I have a custom form class that extends base Zend_Form and specifies the decorators for the form itself and elements as well.
And now I'm in stuck - how to add some particular HTML class to every input element?
The only thing I could think of is to override addElement() but I'm open to better solutions if any.
just another solution:
class My_Form extends Zend_Form
{
public function render(Zend_View_Interface $view = null)
{
foreach ($this->getElements() as $element) {
$element->setAttrib('class', 'default');
}
return parent::render($view);
}
}
sounds like you want a way to automatically assign a unique class to each element.
Expanding on the answer given by b.b3rn4rd, try something like:
class My_Form extends Zend_Form
{
public function render(Zend_View_Interface $view = null)
{
foreach ($this->getElements() as $element) {
//assign the class as some unique identifier that is part of the element
//each element requires a unique name so it's a good place to start
$element->setAttrib('class', $element->getName());
}
return parent::render($view);
}
}
I don't like solutions that inherit Zend_Form, so I devised another way to do this.
<?php
abstract class Application_Style
{
private $_object;
function __construct ($object = null)
{
if (isset ($object))
{
$this->apply ($object);
}
}
function apply ($object)
{
$this->setObject ($object);
if ($this->filter ())
{
$this->onApply ();
}
return $object;
}
function __call ($method, $arguments)
{
return call_user_func_array (array (
$this->getObject (),
$method
), $arguments);
}
abstract protected function onApply ();
protected function filter ()
{
return true;
}
function setObject ($_object)
{
$this->_object = $_object;
}
function getObject ()
{
return $this->_object;
}
}
class Application_Style_ElementClass extends Application_Style
{
function onApply ()
{
foreach ($this->getObject ()
->getElements () as $element)
{
$element->setOptions (array (
'class' => 'test-class'
));
}
}
function filter ()
{
return $this->getObject () instanceof Zend_Form;
}
}
$form = new Zend_Form ();
$form->addElement ('text', 'name');
new Application_Style_ElementClass ($form); // apply the class name
echo $form;
This way you can apply all the styles needed for any form in any order.
Adding HTML class attributes to elements is like this
$element->setAttrib('class', 'text'):
or directly
$element->class = 'text;

Executing calling class' method

class Car
{
$gas= new Gas();
$gas->fill( 'filledHandler' );
function filledHandler()
{
echo 'Gas has been filled!';
}
}
class Gas
{
function fill( $function )
{
// do something here
$function();
}
}
I need to call $function of calling class. Right now, it's looking for a global function
You have to pass the calling instance.
class Car
{
function fillGas()
{
$gas = new Gas();
$gas->fill($this, 'filledHandler');
}
function filledHandler()
{
echo 'Gas has been filled!';
}
}
class Gas
{
function fill($obj, $function)
{
// If you need the class name, use get_class($obj)
$obj->$function();
}
}
class Car
{
function __construct()
{
$gas= new Gas();
$gas->fill($this, 'filledHandler' );
}
function filledHandler()
{
echo 'Gas has been filled!';
}
}
class Gas
{
function fill($object, $function )
{
$object->$function();
}
}
(Ask more question (like what exactly do you want to happen anyway) and get more answer text ^^.)

PHP How to distinguish $this pointer in the inheritance chain?

Please look at the following code snipped
class A
{
function __get($name)
{
if ($name == 'service') {
return new Proxy($this);
}
}
function render()
{
echo 'Rendering A class : ' . $this->service->get('title');
}
protected function resourceFile()
{
return 'A.res';
}
}
class B extends A
{
protected function resourceFile()
{
return 'B.res';
}
function render()
{
parent::render();
echo 'Rendering B class : ' . $this->service->get('title');
}
}
class Proxy
{
private $mSite = null;
public function __construct($site)
{
$this->mSite = $site;
}
public function get($key)
{
// problem here
}
}
// in the main script
$obj = new B();
$obj->render();
Question is: in method 'get' of class 'Proxy', how I extract the corresponding resource file name (resourceFile returns the name) by using only $mSite (object pointer)?
What about:
public function get($key)
{
$file = $this->mSite->resourceFile();
}
But this requires A::resourceFile() to be public otherwise you cannot access the method from outside the object scope - that's what access modifiers have been designed for.
EDIT:
OK - now I think I do understand, what you want to achieve. The following example should demonstrate the desired behavior:
class A
{
private function _method()
{
return 'A';
}
public function render()
{
echo $this->_method();
}
}
class B extends A
{
private function _method()
{
return 'B';
}
public function render()
{
parent::render();
echo $this->_method();
}
}
$b = new B();
$b->render(); // outputs AB
But if you ask me - I think you should think about your design as the solution seems somewhat hacky and hard to understand for someone looking at the code.

Categories