I tried to create a class with the properties like so:
class foo{
private $dbFields['test']=array("mobilePhone","address");
private $dbFields['test2']=array("mobilePhone","address",'colour');
}
but its not valid.
PHP Parse error: syntax error, unexpected '[', expecting ',' or ';' in
I had to do this which has the same result; but is less friendly for me editing in the future
class foo{
private $dbFields=array('test'=>array("mobilePhone","address"),'test2'=>array("mobilePhone","address",'colour'));
}
is there anyway to achieve the original structure or something simular?
You can do it with the following class properties syntax:
<?php
class foo {
private $dbFields = array(
'test' => array("mobilePhone","address"),
'test2' => array("mobilePhone","address","colour")
);
}
If the values are dynamic, and not as it looks (like a reference to database columns), then you should pass the values to the class constructor as suggested by B.Desai answer.
And if the values never change perhaps using a class constant would be nicer (PHP >=5.3.0).
<?php
class foo {
const dbFields = array(
'test' => array("mobilePhone","address"),
'test2' => array("mobilePhone","address","colour")
);
}
Always initialize class member in constructor. This way you can assign any dynamic value also to data member.
class foo{
private $dbFields;
function __construct()
{
$this->dbFields['test']=array("mobilePhone","address");
$this->dbFields['test2']=array("mobilePhone","address",'colour');
}
function getFields()
{
return $this->dbFields;
}
}
$obj = new foo();
print_r($obj->getFields());
Related
Configuration of a project in dev mode with WAMP.
PHP vers 5 and 7 are available.
Just trying to set the project root using filter_input. Could someone please explain why filter input for the protected and private vars inside the class reports a PARSE ERROR? However if used outside the class or inside a function of the class it works.
Is there a better way to do this so that it can be used globally? I find this is called a lot and would prefer to do it once.
$test = filter_input(INPUT_SERVER,'DOCUMENT_ROOT');
echo $test; //good
class FooBar{
protected $_test = filter_input(INPUT_SERVER,'DOCUMENT_ROOT'); //bad - Parse error: syntax error, unexpected '(', expecting ',' or ';'
private $_test2 = filter_input(INPUT_SERVER,'DOCUMENT_ROOT'); //bad - Parse error: syntax error, unexpected '(', expecting ',' or ';'
function __construct() {
}
public function getProducts(){
include_once
(filter_input(INPUT_SERVER,'DOCUMENT_ROOT').'/obj/user.php'); //good
}
}
You can not directly assign a function return value to a property in the class definition.
This is because the function could return different return values, and the class is only a blueprint which you must instantiate as an object to use.
For the objects that are created from your class definition you can initialize any property in the constructor:
class FooBar {
protected $var = null;
private $var2 = null;
function __construct() {
$this->var = func1();
$this->var2 = func2();
}
}
// no parse error
Despite of that, why do you use filter_input on an internal constant? You only need to filter input from the outside, i.e. GET/POST/SESSION content (user input), input read from files, from external APIs etc. But you don't need to use that on internal constants like the DOCUMENT_ROOT:
class FooBar {
private $_docroot = $_SERVER['DOCUMENT_ROOT'];
}
// no parse error
I have the following class in PHP:
class myClass extends AJAX_Callable {
public static $classGlobal = 'myVariable' ;
private static $types_fields = array(
'myArray' => array(
'name' => $classGlobal,
'age' => 'twenty five')
);
}
But this is not working
From the documentation:
Class member variables are called "properties". You may also see them referred to using other terms such as "attributes" or "fields", but for the purposes of this reference we will use "properties". They are defined by using one of the keywords public, protected, or private, followed by a normal variable declaration. This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.
the only way I can think of doing it would be to move things into a constructor. But its still a really weird thing to want to do. There wouldnt be any point in using static as you cant use it in the conventional way.
class myClass extends AJAX_Callable {
public static $classGlobal;
private static $types_fields;
public function __construct() {
// parent::__construct(); // if you have one
$this->classGlobal = 'myVariable';
$this->types_fields = array(
'myArray' => array(
'name' => $this->classGlobal,
'age' => 'twenty five')
);
}
public function getTypes() {
return $this->types_fields;
}
}
$foo = new myClass();
var_dump($foo->getTypes());
fiddle
I'm trying to declare a function and store it on a private static field of my class. I've got something like this:
class MyClass {
private static $myFunction = function() { /* stuff here */ };
}
But I keep getting this error on the line that creates the function:
PHP Parse error: syntax error, unexpected 'function' (T_FUNCTION)…
I'm doing this based on this answer, as well as on what the PHP manual pages say. But it is not working for me. Why? what can I do?
The goal for all of this is that I could be able store the function on an array:
private static $options = [
'function' => MyClass::$myFunction
];
So what do you think is the best way to achieve this? I'm using PHP 5.5.14 in case you wonder.
Update:
I've tried a couple of different approaches. Like this:
class MyClass {
private static function myFunction() { /* Expression */ }
private static $options = [
'function' => MyClass::myFunction()
];
}
But it throws me errors about an unexpected '(':
PHP Parse error: syntax error, unexpected '(', expecting ']'…
And this. Which is the only one that works:
class MyClass {
private static function myFunction() { /* Expression */ }
public static function anotherFunction() {
$options = [ 'function' => MyClass::myFunction() ];
}
}
But I need to have this $options var to be accessible to more methods on the same class, so it's not a solution.
I'd prefer to stay away from constructors, since it is only a helper class and I don't want to mess with instances of it and such things.
You could use this approach
class MyClass{
private static function myFunction(){ echo __FUNCTION__;}
private static $options = [
'function' => ['MyClass', 'myFunction']
];
public static function test(){
$function = self::$options['function'];
$function();
}
}
MyClass::test();
It's possible because array could be callable.
Below is my simplified code where it's giving me errors. It's probably a very simple thing but it's making me confused.
class MyController extends ParentController {
public $pet_list = $this->pet_list_array();
//Parse error: syntax error, unexpected T_VARIABLE in ......
public function pet_list_array() {
return array('cat'=>'Steve\'s Cat',
'dog'=>'Fiona\'s Dog',
'lion'=>'John\'s Lion');
}
}
If I do this instead, I get a different error
public $pet_list = pet_list_array();
//Parse error: syntax error, unexpected '(', expecting ',' or ';' in.....
But if I do this public $pet_list = pet_list_array; (without the round brackets after the function name), it seems to work fine. Is this a normal behaviour? I am a bit unsure.
Your problem is that you can't make a call to a class method in the class definition. Make a __construct() method and set it there, like so:
class MyController extends ParentController {
public $pet_list;
public function __construct(){
$this->pet_list = $this->pet_list_array();
}
public function pet_list_array() {
return array('cat'=>'Steve\'s Cat',
'dog'=>'Fiona\'s Dog',
'lion'=>'John\'s Lion');
}
}
Of course, you probably don't need both $pet_list and pet_list_array() in the same class if they return the same value all the time.
we have a problem [cit.]
I need to assign a callback dynamically within a class, in base of a variable param: my goal is to have just one class (and not a main class and many extender sub-class), and inside this class if a value is X, then the funcitonX must be used, if is Y, the functionY.
I know i cant explain well, i hope my example will do:
class plzComplicateMyLife{
public $vehicle;
public $kindVehicle;
public $dynamicFunction;
public function __construct($vehicle, $kindVehicle){
$this->kindVehicle = $kindVehicle;
$this->vehicle = $vehicle;
switch($kindVehicle){
case 'cycle':
$this->dynamicFunction = "isACycle";
break;
case 'car':
$this->dynamicFunction = "isACar";
break;
}
//here come the problem, i need to call the callback store in dynamicFunction.
//i tried:
//call_user_func($this->$this->dinamicFunction, $this->vehicle);
//error: Catchable fatal error: Object of class plzComplicateMyLife could not be converted to string in [...]
//call_user_func("plzComplicateMyLife::".$this->dynamicFunction);
//Warning: call_user_func(plzComplicateMyLife::isACar) [function.call-user-func]: First argument is expected to be a valid callback in [...]
//$this->dynamicFunction();
//Fatal error: Call to undefined method plzComplicateMyLife::dynamicFunction() in [...]
//so, how can i do that?
}
public function isACycle($vehicle){
echo 'im a cycle, model: '.$vehicle.'<br />';
}
public function isACar($vehicle){
echo 'im a car, model: '.$vehicle.'<br />';
}
//i know this has no sense, in this example at least.
public function printKind(){
//call_user_func($this->$this->dinamicFunction, $this->vehicle);
//call_user_func("plzComplicateMyLife::".$this->dynamicFunction);
//then?
}
}
$maserati = new plzComplicateMyLife('maserati4', 'car');
//then, maybe, outside the class i'll need to recover the callback:
$maserati->printKind();
EDIT:
As Rob said, polymorphism would be really a good solution.
But the problem is that, in this case, i really must have the same declaration for every class instance, changing only the parameters...e.g:
$maserati = new plzComplicateMyLife('maserati4', 'car');
$ducati = new plzComplicateMyLife('maserati4', 'cycle');
//is good
//becose i cant have:
$maserati = new plzComplicateMyLifeWithACar('maserati4');
$ducati = new plzComplicateMyLifeWithACycle('maserati4');
Polymorphism is the way to go here but for future reference you can also do this:
public function printKind() {
$this->{$this->dynamicFunction}($this->vehicle);
}
In response to your edit, could you not do something like this instead?
abstract class MethodOfTransport {
protected $model;
public function __construct($model) {
$this->model = $model;
}
abstract public function printKind();
public static function create($model, $type) {
$object = new $type($model);
return $object;
}
}
class cycle extends MethodOfTransport {
public function printKind() {
echo 'im a cycle, model: '.$this->model.'<br />';
}
}
class car extends MethodOfTransport {
public function printKind() {
echo 'im a car, model: '.$this->model.'<br />';
}
}
$maserati = MethodOfTransport::create('maserati4', 'car');
$maserati->printKind();
$ducati = MethodOfTransport::create('maserati4', 'cycle');
$ducati->printKind();
In PHP you can use specify a method callback using an array as a callback variable (see here), for example:
array( $object, $methodName );
So you could do this
$callback = array($this, $this->dynamicFunction);
call_user_func($callback, $this->vehicle);
Er, why don't you want to use a simple inheritance structure here? If you want different behaviour depending upon the object modelled, then that's pretty much the canonical description of polymorphism.
If you really do want to plough on with callbacks into the same object, then you'll need to do one of two things:
Drop the $vehicle parameter from your callbacks, make them private or protected, and call into them normally, i.e.
call_user_func( array( $this, 'isACycle' ) );
Mark the callback as static, make them private or protected, and call into them as follows:
call_user_func( array( __CLASS__, 'isACycle' ), $this );
Within the non-static callback, access the object's properties via $this in the normal fashion. Note also that I suggest marking the callback as private or protected, in order to prevent unnecessary outside callers; presumably, you don't want them executing the wrong method for each type.