Using constants as default function values in PHP - php

Is this legal?
<?php
function ftw($foo = 'pwnage', $nub = MENU_DEFAULT_VALUE, $odp = ODP_DEFAULT_VALUE) {
//lots_of_awesome_code
}
?>
where MENU_DEFAULT_VALUE and ODP_DEFAULT_VALUE are constants defined previously in the file.

Yes, that is legal.
From the manual:
The default value must be a constant
expression, not (for example) a
variable, a class member or a function
call.
Constants fit that bill perfectly.

In an OOP context, you can also use a class member constant as a default method argument value.
class MyClass
{
const A = 1;
public function __construct($arg = self::A)
{
echo $arg;
}
}

why don't you try ?
Still, just in case you can test right now, the following code :
define('MENU_DEFAULT_VALUE', 10);
define('ODP_DEFAULT_VALUE', 'hello');
function ftw($foo = 'pwnage', $nub = MENU_DEFAULT_VALUE, $odp = ODP_DEFAULT_VALUE) {
var_dump($foo);
var_dump($nub);
var_dump($odp);
}
ftw();
gives this output :
string 'pwnage' (length=6)
int 10
string 'hello' (length=5)
So I'd say that, yes, it is valid :-)

Related

php class static variable inside double-quoted string [duplicate]

How can I get PHP to evaluate a static variable in double quotes?
I want to do something like this:
log("self::$CLASS $METHOD entering");
I've tried all sorts of {} combos to get the variable value of self::$CLASS, but nothing has worked. I've currently settled with string concatenation but it is a pain to type:
log(self::$CLASS . " $METHOD entering");
Sorry, you can't do that. It only works for simple expressions. See here.
Unfortunately there is no way how to do this yet. Example in one of answers here will not work, because {${self::$CLASS}} will not returns content of self::$CLASS, but will returns content of variable with name in self::$CLASS.
Here is an example, which does not returns myvar, but aaa:
$myvar = 'aaa';
self::$CLASS = 'myvar';
echo "{${self::$CLASS}}";
Use an anonymous identity function stored in a variable. This way you will have $ immediately after {:
$I = function($v) { return $v; };
$interpolated = "Doing {$I(self::FOO)} with {$I(self::BAR)}";
(I am using class constants in this example but this will work with static variables too).
I don’t know the answer to your question, but you can show the class name and method using the __METHOD__ magic constant.
<?php
class test {
public $static = 'text';
public $self = __CLASS__;
// static Method
static function author() {
return "Frank Glück";
}
// static variable
static $url = 'https://www.dozent.net';
public function dothis() {
$self = __CLASS__;
echo <<<TEST
{${!${''}=static::author()}} // works
{$self::author()} // works
{$this->self::author()} // works
${!${''}=self::author()} // works
{${$this->self}}::author()}} // don't works
${${self::author()}} // do/don't works but with notice
${#${self::author()}} // works but with # !
TEST;
}
}
$test = 'test'; // this is the trick, put the Classname into a variable
echo "{$test::author()} {$$test::$url}";
echo <<<HTML
<div>{$test::author()}</div>
<div>{$$test::$url}</div>
HTML;
$test = new test();
$test->dothis();
I know this is an old question but I find it odd that noone has suggested the [sprintf][1] function yet.
say:
<?php
class Foo {
public static $a = 'apple';
}
you would use it with:
echo sprintf( '$a value is %s', Foo::$a );
so on your example its:
log(
sprintf ( ' %s $METHOD entering', self::$CLASS )
);
//define below
function EXPR($v) { return $v; }
$E = EXPR;
//now you can use it in string
echo "hello - three is equal to $E(1+2)";
Just live with the concatenation. You'd be surprised how inefficient variable interpolation in strings can be.
And while this could fall under the umbrella of pre-optimization or micro-optimization, I just don't think you actually gain any elegance in this example.
Personally, if I'm gonna make a tiny optimization of one or the other, and my choices are "faster" and "easier to type" - I'm gonna choose "faster". Because you only type it a few times, but it's probably going to execute thousands of times.
Yes this can be done:
log("{${self::$CLASS}} $METHOD entering");

understanding __construct($foo = null) and check if $foo is true then

How $mysettings can be true while we are initializing it with null? is this a method to prevent SQL injection? It would be appreciated if you could explain the code below.
public function __construct($mysettings = null)
{
$this->shop_version = Mage::getVersion();
$this->moduleversion = Mage::getConfig()->getModuleConfig('Messagemodule')->version;
$this->apppid = Mage::getStoreConfig('magemessage/appId');
if (empty($this->apppid)) {
$this->apppid = 'no-appId';
}
$this->connectortype = ($settingvariable = Mage::getStoreConfig('Messagemodule/magemessage/connector', 0)) ? $settingvariable : 'auto';
if ($mysettings) {
$this->connectortype = $mysettings;
}
}
When you specify a default value in a PHP method (including a constructor), that's all it is - a default.
So if you have
class Foo {
public function __construct($mysettings = null) {
...
}
}
then you are providing two ways of constructing the class. You can either call
$foo = new Foo();
with no arguments, in which case $mysettings will be initialised to null. Or you can call
$settings = array('key' => 'value');
$foo = new Foo($settings);
in which case the $settings array will be passed into the new instance. The benefit this provides is that you don't need to provide an empty array to new instances for which you don't need custom settings; you can just omit the argument.
The check if ($mysettings)... in the class ensures that the settings are only used if they are provided - a PHP if statement can operate on lots of different types, not just booleans. In this case, if the variable is null, the condition will evaluate to false.
Have a look at this code:
<?php
function required($something)
{
echo $something;
}
required();
It throws a fatal error, because $something was required, but not passed. https://3v4l.org/fIKB9
Now look here:
<?php
function required($something = 'hello')
{
echo $something;
}
required();
required(' R.Toward');
Which outputs Hello R.Toward https://3v4l.org/nQF8r
So in essence, it is a way of setting a default optional value.

Define const as a variable

I looked up a few solutions, but nothing that's able to solve it. I realize that constants are not supposed to be modifiable hence the whole point of the word "constant".
In this case I'm dealing with an API class that goes like this
class GetAdGroups {
const CAMPAIGN_ID = "";
I have to pass a value to CAMPAIGN_ID, but it can't be hard coded as a string.
So the following is not an option:
const CAMPAIGN_ID = 123;
I tried going with "define"
class GetAdGroups {
$my_var = 123;
define("CAMPAIGN_ID", "$my_var");
But it throws an error and when I define it outside the class scope, it also throws an error that the constant is not found.
Not sure what else to try. Pretty new to OOP and would appreciate your help
Check this what are new features in php 5.6
<?php
const ONE = 1;
const TWO = ONE * 2;
class C {
const THREE = TWO + 1;
const ONE_THIRD = ONE / self::THREE;
const SENTENCE = 'The value of THREE is '.self::THREE;
public function f($a = ONE + self::THREE) {
return $a;
}
}
echo (new C)->f()."\n";
echo C::SENTENCE;
?>
this may help you. You can use expression as constant value here.
Note:-
It is now possible to provide a scalar expression involving numeric
and string literals and/or constants in contexts where PHP previously
expected a static value, such as constant and property declarations
and default function arguments.
Yes, this is quite impossible, even you can not do like
function bar(){
return 'Hi';
}
class C {
const SENTENCE = bar();
//const SENTENCE = :SELF:foo();
public static foo(){
return "Hello';
}
}
echo C::SENTENCE;
#u_mulder is very correct.
You have missed reading the documentation correctly.
/**
* This example gets all ad groups in a campaign. To get campaigns, run
* GetCampaigns.php.
*/
Check this class instead.
here your campaign id is variable.
foreach ($page->getEntries() as $campaign) {
printf(
"Campaign with ID %d and name '%s' was found.\n",
$campaign->getId(),
$campaign->getName()
);
}
If you are using PHP 7+ then you can use this way .
// Works as of PHP 7
define('ALLVAR', array(
'dog',
'cat',
'bird'
));
echo ALLVAR[1]; // outputs "cat"
If you are using php < 7 Then use this way .
define ("ALLVAR", serialize (array ('dog','cat','bird')));
$my_const = unserialize(ALLVAR);
Inside your Class you can define a function for constants. Like below
class GetAdGroups{
public $options = array(
'app_id' => 'hello',
);
public function getConstant($key){
return $this->options[$key];
}
}
$a = new GetAdGroups();
print_r($a->getConstant('app_id'));

PHP static variables in double quotes

How can I get PHP to evaluate a static variable in double quotes?
I want to do something like this:
log("self::$CLASS $METHOD entering");
I've tried all sorts of {} combos to get the variable value of self::$CLASS, but nothing has worked. I've currently settled with string concatenation but it is a pain to type:
log(self::$CLASS . " $METHOD entering");
Sorry, you can't do that. It only works for simple expressions. See here.
Unfortunately there is no way how to do this yet. Example in one of answers here will not work, because {${self::$CLASS}} will not returns content of self::$CLASS, but will returns content of variable with name in self::$CLASS.
Here is an example, which does not returns myvar, but aaa:
$myvar = 'aaa';
self::$CLASS = 'myvar';
echo "{${self::$CLASS}}";
Use an anonymous identity function stored in a variable. This way you will have $ immediately after {:
$I = function($v) { return $v; };
$interpolated = "Doing {$I(self::FOO)} with {$I(self::BAR)}";
(I am using class constants in this example but this will work with static variables too).
I don’t know the answer to your question, but you can show the class name and method using the __METHOD__ magic constant.
<?php
class test {
public $static = 'text';
public $self = __CLASS__;
// static Method
static function author() {
return "Frank Glück";
}
// static variable
static $url = 'https://www.dozent.net';
public function dothis() {
$self = __CLASS__;
echo <<<TEST
{${!${''}=static::author()}} // works
{$self::author()} // works
{$this->self::author()} // works
${!${''}=self::author()} // works
{${$this->self}}::author()}} // don't works
${${self::author()}} // do/don't works but with notice
${#${self::author()}} // works but with # !
TEST;
}
}
$test = 'test'; // this is the trick, put the Classname into a variable
echo "{$test::author()} {$$test::$url}";
echo <<<HTML
<div>{$test::author()}</div>
<div>{$$test::$url}</div>
HTML;
$test = new test();
$test->dothis();
I know this is an old question but I find it odd that noone has suggested the [sprintf][1] function yet.
say:
<?php
class Foo {
public static $a = 'apple';
}
you would use it with:
echo sprintf( '$a value is %s', Foo::$a );
so on your example its:
log(
sprintf ( ' %s $METHOD entering', self::$CLASS )
);
//define below
function EXPR($v) { return $v; }
$E = EXPR;
//now you can use it in string
echo "hello - three is equal to $E(1+2)";
Just live with the concatenation. You'd be surprised how inefficient variable interpolation in strings can be.
And while this could fall under the umbrella of pre-optimization or micro-optimization, I just don't think you actually gain any elegance in this example.
Personally, if I'm gonna make a tiny optimization of one or the other, and my choices are "faster" and "easier to type" - I'm gonna choose "faster". Because you only type it a few times, but it's probably going to execute thousands of times.
Yes this can be done:
log("{${self::$CLASS}} $METHOD entering");

PHP Constants Containing Arrays?

This failed:
define('DEFAULT_ROLES', array('guy', 'development team'));
Apparently, constants can't hold arrays. What is the best way to get around this?
define('DEFAULT_ROLES', 'guy|development team');
//...
$default = explode('|', DEFAULT_ROLES);
This seems like unnecessary effort.
Since PHP 5.6, you can declare an array constant with const:
<?php
const DEFAULT_ROLES = array('guy', 'development team');
The short syntax works too, as you'd expect:
<?php
const DEFAULT_ROLES = ['guy', 'development team'];
If you have PHP 7, you can finally use define(), just as you had first tried:
<?php
define('DEFAULT_ROLES', array('guy', 'development team'));
PHP 5.6+ introduced const arrays - see Andrea Faulds' answer.
You can also serialize your array and then put it into the constant:
# define constant, serialize array
define ("FRUITS", serialize (array ("apple", "cherry", "banana")));
# use it
$my_fruits = unserialize (FRUITS);
You can store them as static variables of a class:
class Constants {
public static $array = array('guy', 'development team');
}
# Warning: array can be changed lateron, so this is not a real constant value:
Constants::$array[] = 'newValue';
If you don't like the idea that the array can be changed by others, a getter might help:
class Constants {
private static $array = array('guy', 'development team');
public static function getArray() {
return self::$array;
}
}
$constantArray = Constants::getArray();
EDIT
Since PHP5.4, it is even possible to access array values without the need for intermediate variables, i.e. the following works:
$x = Constants::getArray()['index'];
If you are using PHP 5.6 or above, use Andrea Faulds answer
I am using it like this. I hope, it will help others.
config.php
class app{
private static $options = array(
'app_id' => 'hello',
);
public static function config($key){
return self::$options[$key];
}
}
In file, where I need constants.
require('config.php');
print_r(app::config('app_id'));
This is what I use. It is similar to the example provided by soulmerge, but this way you can get the full array or just a single value in the array.
class Constants {
private static $array = array(0 => 'apple', 1 => 'orange');
public static function getArray($index = false) {
return $index !== false ? self::$array[$index] : self::$array;
}
}
Use it like this:
Constants::getArray(); // Full array
// OR
Constants::getArray(1); // Value of 1 which is 'orange'
You can store it as a JSON string in a constant. And application point of view, JSON can be useful in other cases.
define ("FRUITS", json_encode(array ("apple", "cherry", "banana")));
$fruits = json_decode (FRUITS);
var_dump($fruits);
PHP 7+
As of PHP 7, you can just use the define() function to define a constant array :
define('ANIMALS', [
'dog',
'cat',
'bird'
]);
echo ANIMALS[1]; // outputs "cat"
I know it's a bit old question, but here is my solution:
<?php
class Constant {
private $data = [];
public function define($constant, $value) {
if (!isset($this->data[$constant])) {
$this->data[$constant] = $value;
} else {
trigger_error("Cannot redefine constant $constant", E_USER_WARNING);
}
}
public function __get($constant) {
if (isset($this->data[$constant])) {
return $this->data[$constant];
} else {
trigger_error("Use of undefined constant $constant - assumed '$constant'", E_USER_NOTICE);
return $constant;
}
}
public function __set($constant,$value) {
$this->define($constant, $value);
}
}
$const = new Constant;
I defined it because I needed to store objects and arrays in constants so I installed also runkit to php so I could make the $const variable superglobal.
You can use it as $const->define("my_constant",array("my","values")); or just $const->my_constant = array("my","values");
To get the value just simply call $const->my_constant;
Yes, You can define an array as constant. From PHP 5.6 onwards, it is possible to define a constant as a scalar expression, and it is also possible to define an array constant. It is possible to define constants as a resource, but it should be avoided, as it can cause unexpected results.
<?php
// Works as of PHP 5.3.0
const CONSTANT = 'Hello World';
echo CONSTANT;
// Works as of PHP 5.6.0
const ANOTHER_CONST = CONSTANT.'; Goodbye World';
echo ANOTHER_CONST;
const ANIMALS = array('dog', 'cat', 'bird');
echo ANIMALS[1]; // outputs "cat"
// Works as of PHP 7
define('ANIMALS', array(
'dog',
'cat',
'bird'
));
echo ANIMALS[1]; // outputs "cat"
?>
With the reference of this link
Have a happy coding.
Can even work with Associative Arrays.. for example in a class.
class Test {
const
CAN = [
"can bark", "can meow", "can fly"
],
ANIMALS = [
self::CAN[0] => "dog",
self::CAN[1] => "cat",
self::CAN[2] => "bird"
];
static function noParameter() {
return self::ANIMALS[self::CAN[0]];
}
static function withParameter($which, $animal) {
return "who {$which}? a {$animal}.";
}
}
echo Test::noParameter() . "s " . Test::CAN[0] . ".<br>";
echo Test::withParameter(
array_keys(Test::ANIMALS)[2], Test::ANIMALS["can fly"]
);
// dogs can bark.
// who can fly? a bird.
if you're using PHP 7 & 7+, you can use fetch like this as well
define('TEAM', ['guy', 'development team']);
echo TEAM[0];
// output from system will be "guy"
Using explode and implode function we can improvise a solution :
$array = array('lastname', 'email', 'phone');
define('DEFAULT_ROLES', implode (',' , $array));
echo explode(',' ,DEFAULT_ROLES ) [1];
This will echo email.
If you want it to optimize it more you can define 2 functions to do the repetitive things for you like this :
//function to define constant
function custom_define ($const , $array) {
define($const, implode (',' , $array));
}
//function to access constant
function return_by_index ($index,$const = DEFAULT_ROLES) {
$explodedResult = explode(',' ,$const ) [$index];
if (isset ($explodedResult))
return explode(',' ,$const ) [$index] ;
}
Hope that helps . Happy coding .
Doing some sort of ser/deser or encode/decode trick seems ugly and requires you to remember what exactly you did when you are trying to use the constant. I think the class private static variable with accessor is a decent solution, but I'll do you one better. Just have a public static getter method that returns the definition of the constant array. This requires a minimum of extra code and the array definition cannot be accidentally modified.
class UserRoles {
public static function getDefaultRoles() {
return array('guy', 'development team');
}
}
initMyRoles( UserRoles::getDefaultRoles() );
If you want to really make it look like a defined constant you could give it an all caps name, but then it would be confusing to remember to add the '()' parentheses after the name.
class UserRoles {
public static function DEFAULT_ROLES() { return array('guy', 'development team'); }
}
//but, then the extra () looks weird...
initMyRoles( UserRoles::DEFAULT_ROLES() );
I suppose you could make the method global to be closer to the define() functionality you were asking for, but you really should scope the constant name anyhow and avoid globals.
You can define like this
define('GENERIC_DOMAIN',json_encode(array(
'gmail.com','gmail.co.in','yahoo.com'
)));
$domains = json_decode(GENERIC_DOMAIN);
var_dump($domains);
Constants can only contain scalar values, I suggest you store the serialization (or JSON encoded representation) of the array.
If you are looking this from 2009, and you don't like AbstractSingletonFactoryGenerators, here are a few other options.
Remember, arrays are "copied" when assigned, or in this case, returned, so you are practically getting the same array every time. (See copy-on-write behaviour of arrays in PHP.)
function FRUITS_ARRAY(){
return array('chicken', 'mushroom', 'dirt');
}
function FRUITS_ARRAY(){
static $array = array('chicken', 'mushroom', 'dirt');
return $array;
}
function WHAT_ANIMAL( $key ){
static $array = (
'Merrick' => 'Elephant',
'Sprague' => 'Skeleton',
'Shaun' => 'Sheep',
);
return $array[ $key ];
}
function ANIMAL( $key = null ){
static $array = (
'Merrick' => 'Elephant',
'Sprague' => 'Skeleton',
'Shaun' => 'Sheep',
);
return $key !== null ? $array[ $key ] : $array;
}

Categories