Is anyone familiar with working with this library: https://github.com/eloquent/enumeration
I am having trouble converting the instance of the constant back to the constant value.
class TestEnum extends AbstractEnumeration
{
const THING1 = 'test1';
const THING2 = 'test2';
}
class DoStuff
{
public function action(TestEnum $test)
{
if($test === 'test1') {
echo 'THIS WORKS';
}
}
}
$enumTest = TestEnum::THING1();
$doStuff = new DoStuff();
$doStuff->action($enumTest);
My goal is to have the method action print 'THIS WORKS'. Because $test is an instance of TestEnum, this would not evaluate to true.
You're close, but there are two problems:
Case matters. Thing1 != THING1
$test, when treated as a string, evaluates to its key THING1. You want its value $test->value()
Example:
class TestEnum extends AbstractEnumeration
{
const THING1 = 'test1';
const THING2 = 'test2';
}
class DoStuff
{
public function action(TestEnum $test)
{
if($test->value() === 'test1') {
echo 'THIS WORKS';
}
}
}
$enumTest = TestEnum::THING1();
$doStuff = new DoStuff();
$doStuff->action($enumTest);
Output:
THIS WORKS
Related
Are there any actual difference between the two ways to get the value by reference?
Way 1
<?php
class foo {
public $value = 42;
public function &getValue() {
return $this->value;
}
}
$obj = new foo;
$myValue = &$obj->getValue();
// $myValue is a reference to $obj->value, which is 42.
$obj->value = 2;
echo $myValue;
// prints the new value of $obj->value, i.e. 2.
?>
Way 2
<?php
class foo {
public $value = 42;
public function getValue() {
return $this->value;
}
}
$obj = new foo;
$myValue = &$obj->value;
$obj->value = 2;
echo $myValue;
?>
In both cases 2 is printed. So why does one need the getValue() function then? The first example is taken from the PHP Manual.
You need the first approach if class fields don't have a modifier 'public'. In this case you can't get a reference to the field outside the class. See example:
<?php
class foo
{
protected $value = 1;
public function setValue($value)
{
$this->value = $value;
}
public function &getValue()
{
return $this->value;
}
}
$obj = new foo;
$myValue = &$obj->getValue();
$obj->setValue(2);
echo $myValue;
?>
Assume I have an object with 3 properties:
protected $validMainStatements;
protected $validPrimaryStatements;
protected $validSecondaryStatements;
And I got the following method:
public function selectType($stmt) {
$stmtParts = MainServerInterface::parse($stmt);
$type = $stmtParts[0] //returns either Main, Primary or Secondary
}
Depending on the value of type, I want to use the associated property. A simple implementation would be:
public function selectType($stmt) {
$stmtParts = MainServerInterface::parse($stmt);
$type = $stmtParts[0] //returns either Main, Primary or Secondary
if($type === "Main") {
$usedProp = $this->validMainStatements;
} elseif($type === "Primary") {
$usedProp = $this->validPrimaryStatements;
} elseif($type === "Secondary") {
$usedProp = $this->validSecondaryStatements;
}
}
I think I don't have to mention that this is ugly and uncomfortable to use. Is there a way to implement this in an easier way? Something like (pseudocode):
$usedProp = $"valid".$type."Statements";
<?php
class Foo {
protected $validMainStatements = 1;
protected $validPrimaryStatements = 2;
protected $validSecondaryStatements = 3;
public function bar() {
$type = 'Primary';
return $this->{'valid'.$type.'Statements'};
}
}
$foo = new Foo;
echo $foo->bar();
see Variable variables - Example #1 Variable property example
-- edit and btw:
I'd rather do it this way:
<?php
class Foo {
protected $validStatements = [
'Main' => 1,
'Primary' => 2,
'Secondary' => 3
];
public function bar() {
$type = 'Primary';
return $this->validStatements[$type];
}
}
$foo = new Foo;
echo $foo->bar();
Demo
Try like below
$usedProp = $this->{"valid".$type."Statements"};
Test
<?php
class test {
public $validMainStatements = 'hello';
}
$instance = new test;
$type = 'Main';
echo $instance->{"valid".$type."Statements"};
?>
Result
hello
Just use variable variables.
$variableName = 'valid'.$type.'Statements';
$this->{$variableName};
I'm trying to pass a variable to a method in an extended class, but it's not working.
Here's the sample code:
class set2 extends set1
{
function Body($variable) {
}
}
$start2 = new set2();
$start2->Body('some text');
The last line is the part I'm trying to get to work. I'm not sure if I should have a constructor instead to do it or how it's best to get it to work.
I figured it out. I just added a public variable instead and passed its value like this:
class set2 extends set1
{
public $variable = NULL;
function Body() {
echo $this->variable;
}
}
$start2 = new set2();
$start2->variable = 'Some Text';
Three different ways of doing what I think you're trying to do:
class set1
{
protected $headVariable;
function Head() {
echo $this->headVariable;
}
function Body($variable) {
echo $variable;
}
function Foot() {
echo static::$footVariable;
}
}
class set2 extends set1
{
protected static $footVariable;
function Head($variable) {
$this->headVariable = $variable;
parent::Head();
}
function Body($variable) {
parent::Body($variable);
}
function Foot($variable) {
self::$footVariable = $variable;
parent::Foot();
}
}
$start2 = new set2();
$start2->Head('some text');
$start2->Body('some more text');
$start2->Foot('yet more text');
I need to know do we have to check input parameters of class methods in PHP OOP or not?
For example imagine the method below:
public function show_message($message)
{
echo $message;
}
What is the best solution if programmer don't pass the message parameter to method? Let PHP to show it's warning or run time error or do something else ?
The "best" solution depends on what you want the method to do exactly, but generally, I'd suggest a combination of type-hinting and default values:
class Foo
{
public function doSomething ($message = 'None')
{
echo $message;
}
public function somethingElse (array $foo = array())
{
echo '<pre>';
print_r($foo);
echo '</pre>';//will always be an array
}
public function onlyMyself (Foo $instance)
{
return $instance->doSomething('I know this method exists');
}
public function myselfOrNothing(Foo $instance = null)
{
if ($instance === null)
{
return $this->doSomething('No instance provided');
}
return $instance->doSomething('Instance provided to '.__METHOD__);
}
}
$foo = new Foo;
$bar = new Bar;
$foo->onlyMyself($bar);//works fine
$foo->onlyMyself(array());//fails
$bar->myselfOrNothing();//works
$bar->somethingElse();//ok...
etcetera, you get the basic principle.
Note that, if you're using an abstract parent class (or just any old parent class), type-hinting a parent allows for the child to be passed, too:
class Bar extends Foo
{
}
class Foobar extends Bar
{
}
$fb = new Foobar;
$b = new Bar;
public function someClass(Foo $instance)
{//accepts instances of Foo, Bar and Foobar...
echo get_class($instance);//can echo any class name
}
Allow for a default value, then trap for that default. This puts control of what you do in your hands rather than the simple default PHP behaviour
public function show_message($message = "\x00")
{
if ($message === "\x00") {
// decide how critical this argument actually is, and react appropriately
throw new BadMethodCallException("The message argument is critical and must be passed to this method");
// or simply apply a default if it isn't critical
$message = 'Hello World';
}
echo $message;
}
I think the type of error should depend on how important the function is and if that is enough of a reason to stop execution if the parameter is not there.
if you are talking about input parameters validation. you can do something like this.
public function show_message($message = '') {
$result = 'No message';
if (!empty($message)) {
if (is_bool($message)) {
$result = 'It is a boolean';
}
if (is_int($message)) {
$result = 'It is a integer';
}
if (is_float($message)) {
$result = 'It is a float';
}
if (is_string($message)) {
$result = 'It is a string';
}
if (is_array($message)) {
$result = 'It is an array';
}
if (is_object($message)) {
$result = 'It is an object';
}
}
return $result;
}
i have something like this:
class foo
{
//code
}
$var = new foo();
$var->newVariable = 1; // create foo->newVariable
$var->otherVariable = "hello, im a variable"; //create foo->otherVariable
i can get in class foo a list of all variables defined outside by user (newVariable, otherVariable,etc)? Like this:
class foo
{
public function getUserDefined()
{
// code
}
}
$var = new foo();
$var->newVariable = 1; // create foo->newVariable
$var->otherVariable = "hello, im a variable"; //create foo->otherVariable
var_dump($var->getUserDefined()); // returns array ("newVariable","otherVariable");
Thanks!.
Yes, using get_object_vars() and get_class_vars():
class A {
var $hello = 'world';
}
$a = new A();
$a->another = 'variable';
echo var_dump(get_object_vars($a));
echo '<hr />';
// Then, you can strip off default properties using get_class_vars('A');
$b = get_object_vars($a);
$c = get_class_vars('A');
foreach ($b as $key => $value) {
if (!array_key_exists($key,$c)) echo $key . ' => ' . $value . '<br />';
}
What is your goal? Imo it's not very good practice (unless you really know what you are doing). Maybe it's good idea consider create some class property like "$parameters" and then create setter and getter for this and use it in this way:
class foo {
private $variables;
public function addVariable($key, $value) {
$this->variables[$key] = $value;
}
public function getVariable($key) {
return $this->variables[$key];
}
public function hasVariable($key) {
return isset($this->variables[$key]);
}
(...)
}
$var = new foo();
$var->addVariable('newVariable', 1);
$var->addVariable('otherVariable', "hello, im a variable");
And then you can use it whatever you want, for example get defined variable:
$var->getVariable('otherVariable');
To check if some var is already defined:
$var->hasVariable('someVariable')
get_class_vars() http://php.net/manual/en/function.get-class-vars.php
You question is not clear though.
$var->newVariable = 1;
there are two possible contex of above expression
1) you are accessing class public variables.
like
class foo
{
public $foo;
public function method()
{
//code
}
}
$obj_foo = new foo();
$obj_foo->foo = 'class variable';
OR
2) you are defining class variable runtime using _get and _set
class foo
{
public $foo;
public $array = array();
public function method()
{
//code
}
public function __get()
{
//some code
}
public function __set()
{
// some code
}
}
$obj_foo = new foo();
$obj_foo->bar= 'define class variable outside the class';
so in which context your question is talking about?