I have a simple class in PHP with a constant. In the constructor I'd like to use this constant in a for loop, however both the IDE and PHP say:
Notice: Use of undefined constant DECK_SUITS - assumed 'DECK_SUITS' in /../Deck.php on line 18
Here's the code of my class:
class Deck
{
private $cards = [];
const DECK_SUITS = [Suit::Club, Suit::Diamond, Suit::Heart, Suit::Spade];
const DECK_RANKS = [Rank::Ace, Rank::Two, Rank::Three, Rank::Four, Rank::Five, Rank::Six, Rank::Seven, Rank::Eight, Rank::Nine,
Rank::Ten, Rank::Jack, Rank::Queen, Rank::King];
public function __construct() {
foreach(DECK_SUITS as $suit) {
foreach(DECK_RANKS as $rank) {
$card = new Card($suit, $rank);
$this->cards[] = $card;
}
}
}
So this error is shown for both DECK_SUITS as well as DECK_RANKS in my foreach loop.
I can't find what's wrong with my code.
That's because they're class constants not global constants (created using the define() function), and need to be referenced differently, identifying the class that they're defined in:
foreach(Deck::DECK_SUITS as $suit) {
foreach(Deck::DECK_RANKS as $rank) {
or self::DECK_SUITS and self::DECK_RANKS from within the class where they're defined
Related
I'm trying to iterate through the variables within a PHP class that contains an SplEnum. It doesn't work. Here's the code:
class enum extends SplEnum { const First = 1; }
class fruit
{
public $enum;
public $variable = 2;
public function __construct(enum $enum)
{
$this->enum = $enum;
}
}
$apple = new fruit(new enum(enum::First));
foreach ($apple as $key => $value) {
echo "[$key] => $value\n";
}
This is the output:
[enum] => 1
PHP Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Value not a const in enum enum' in /home/test.php:16
Stack trace:
#0 /home/test.php(16): unknown()
#1 {main}
thrown in /home/test.php on line 16
It seems that what is happening is that the foreach loop is trying to turn each class variable into an enum. How do I correctly iterate through the variables in the class?
The SPL Lib is known to be a buggy one.
You can switch the order of the variable declaration to
public $variable = 2;
public $enum;
And the example will work.
It will also work if you delete the enum property declaration altogether.
class fruit
{
public $variable = 2;
public function __construct(enum $enum)
{
$this->enum = $enum;
}
}
Maybe your best bet is to avoid it, or keep it private/protected.
Why does the following code give me an exception saying that my constant isn't defined
MyClass::myFunction(MyClass::MY_CONST); // THIS GIVES THE ERROR
// This is the class..
class MyClass {
const MY_CONST = 'BLA';
public static function myFunction($key) {
if (!defined($key)) {
throw new Exception("$key is not defined as a constant");
}
}
}
I've tried with
if (!defined($key)) {}
if (!defined(self::$key)) {}
if (!defined(__CLASS__ . $key)) {}
You have to pass it as a string:
public static function myFunction($key) {
if (!defined('self::'.$key)) {
throw new Exception("$key is not defined as a constant");
}
}
MyClass::myFunction('MY_CONST');
As Daniele D points out, for starts you're calling it with the value of the constant, not its name.
And defined needs a different syntax for the parameter when checking class constants, rather than defined constants. It should be
if (!defined('self::' . $key)) {
You need to pass the entire class name and constant as a string.
Like:
MyClass::myFunction('MyClass::MY_CONST');
I have trouble accessing a constant of a class via the object operator(->).
I have these 2 classes:
class withConstant {
const MY_CONSTANT = 5;
}
class usingConstant {
public $class = null;
function __construct() {
$this->class = new withConstant();
}
}
When I do this:
$myClass = new usingConstant();
echo $myClass->class::MY_CONSTANT;
I get an error Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM). However, I can get around it with this:
$myClass = new usingConstant();
$myClass = &$myClass->class;
echo $myClass::MY_CONSTANT;
I prefer to access the constant without assigning the member variable to another variable first.
This is the closest I can come to what you're actually after achieving unfortunately:
echo constant(get_class($myClass->class).'::MY_CONSTANT');
Note that this is incredibly inefficient, since it looks up the class to determine it's name, then looks it up again to reference the constant.
You can make a getter function in withConstant and call that.
class withConstant {
const MY_CONSTANT = 5;
function getConstant(){
return self::MY_CONSTANT;
}
}
Then you can call that function:
$myClass = new usingConstant();
echo $myClass->class->getConstant();
My class looks similar to this:
class Foo {
const UNKNOWN = 2;
public function doStuff($var) {
if($var==UNKNOWN) {
echo "Unknown state";
return;
}
// other stuff
}
}
However, I'm getting this error in doStuff():
Use of undefined constant UNKNOWN - assumed 'UNKNOWN'
What am I doing wrong? Can't I define custom constants?
You must use self:: or the class name when accessing the constant in your class:
if($var == self::UNKNOWN) {
echo "Unknown state";
return;
}
Documentation has the example of defining the constants in the PHP class.
self:: will help
class Constants
{
//define('MIN_VALUE', '0.0'); WRONG - Works OUTSIDE of a class definition.
//define('MAX_VALUE', '1.0'); WRONG - Works OUTSIDE of a class definition.
const MIN_VALUE = 0.0; // RIGHT - Works INSIDE of a class definition.
const MAX_VALUE = 1.0; // RIGHT - Works INSIDE of a class definition.
public static function getMinValue()
{
return self::MIN_VALUE;
}
public static function getMaxValue()
{
return self::MAX_VALUE;
}
}
for using every dynamic field in php you must call $this->field
and for using every static field and const in php you must call self::field
example:
class ApiController {
public static $static= "";
public $dynamic= "";
public function __construct() {
$a=$this->$dynamic;
$b=self::$static;
}
}
I'm trying to use self instead of typing the class name inside propery_exists function as follows :
private static function instantiate($record){
$user = new self;
foreach($record as $name => $value){
if(isset($user->$name) || property_exists(self, $name)){
$user->$name = $value;
}
}
return $user;
}
But when i ran this script it get an error :
Notice: Use of undefined constant self - assumed 'self' in
/var/www/photo_gallery/includes/User.php on line 36
Line 36 is the line where property_exists method is called.
When i change self to User (the class name). It works perfectly.
I want to know why using self is giving such a notice ? Doesn't self refer to the class?
Use self to refer to the current class. Not class name.
Try using magic constants:
if(isset($user->$name) || property_exists(__CLASS__, $name)){
From php manual: __CLASS__
The class name. (Added in PHP 4.3.0) As of PHP 5 this constant returns the class name as it was declared (case-sensitive). In PHP 4 its value is always lowercased. The class name includes the namespace it was declared in (e.g. Foo\Bar). Note that as of PHP 5.4 CLASS works also in traits. When used in a trait method, CLASS is the name of the class the trait is used in.
PHP Manual
An example:
class Test {
public function __construct(){
echo __CLASS__;
}
}
$test = new Test();
Output:
Test
You can use self::class this way you avoid magic constants.
As an addition you can use something like this to make an instance from an array:
public function __construct(array $array)
{
foreach ($array as $key => $value) {
if (property_exists(self::class, $key)) {
$this->$key = $value;
}
}
}