Can I use string concatenation to define a class CONST in PHP? - php

I know that you can create global constants in terms of each other using string concatenation:
define('FOO', 'foo');
define('BAR', FOO.'bar');
echo BAR;
will print 'foobar'.
However, I'm getting an error trying to do the same using class constants.
class foobar {
const foo = 'foo';
const foo2 = self::foo;
const bar = self::foo.'bar';
}
foo2 is defined without issue, but declaring const bar will error out
Parse error: syntax error, unexpected '.', expecting ',' or ';'
I've also tried using functions like sprintf() but it doesn't like the left paren any more than the string concatenator '.'.
So is there any way to create class constants in terms of each other in anything more than a trivial set case like foo2?

The only way is to define() an expression and then use that constant in the class
define('foobar', 'foo' . 'bar');
class Foo
{
const blah = foobar;
}
echo Foo::blah;
Another option is to go to bugs.php.net and kindly ask them to fix this.

Imho, this question deserves an answer for PHP 5.6+, thanks to #jammin comment
Since PHP 5.6 you are allowed to define a static scalar expressions for a constant:
class Foo {
const BAR = "baz";
const HAZ = self::BAR . " boo\n";
}
Although it is not part of the question, one should be aware of the limits of the implementation. The following won't work, although it is static content (but might be manipulated at runtime):
class Foo {
public static $bar = "baz";
const HAZ = self::$bar . " boo\n";
}
// PHP Parse error: syntax error, unexpected '$bar' (T_VARIABLE), expecting identifier (T_STRING) or class (T_CLASS)
class Foo {
public static function bar () { return "baz";}
const HAZ = self::bar() . " boo\n";
}
// PHP Parse error: syntax error, unexpected '(', expecting ',' or ';'
For further information take a look at: https://wiki.php.net/rfc/const_scalar_exprs and http://php.net/manual/en/language.oop5.constants.php

Always fall back to the trusty manual for stuff like this.
Regarding constants:
The value must be a constant
expression, not (for example) a
variable, a property, a result of a
mathematical operation, or a function
call.
So... "no" would be the answer :D

For class constants, you can't assign anything other than a constant expression. Quoting the PHP manual:
"The value must be a constant expression, not (for example) a variable, a property, a result of a mathematical operation, or a function call. "

This may not be directly what you're looking for, but I came across this thread, so here is a solution that I used for an issue I was having (based off of #user187291's answer):
define('app_path', __DIR__ . '/../../');
const APPLICATION_PATH = app_path;
.
.
.
require_once(APPLICATION_PATH . "some_directory/some_file.php");
.
.
.
Seems to work great!

Related

Why am I not able to use a number in php public function class at starting?

So I'm trying to create a page, and the software I use, uses the below code to create pages:
public function 2testnew()
{
$pagetitle = "testnew";
$this->SetVars(compact('pagetitle'));
return $this->render(dirname(__DIR__) . "/" . self::_VIEWS_PATH . "/" . self::_PAGES_DIR, __FUNCTION__, TEMPLATE_NAME);
}
Unfortunately, when I start my page name with "2" at the beginning of the page name, my website stops working, and also on Notepad++, it shows "2" in orange color, meaning there's something wrong.
I'm a beginner at PHP, so please guide me. How do I achieve a class starting with a number instead because I want to create a page that has a number at the beginning of the name?
Thank you for your help.
There's something incomplete in your error reporting settings. When properly configured you'd get something like:
Parse error: syntax error, unexpected '2' (T_LNUMBER)
Why doesn't PHP parser expect a 2 character there? Because it isn't a valid class method name. It's admittedly not documented where you'd expect it to but it can be found in the functions chapter (class methods follow the same rules as regular functions):
Function names follow the same rules as other labels in PHP. A valid function name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$.
If you absolutely need to, how can you? You can hack it with e.g. magic methods:
class MyController
{
private function twotestnew($one, $two)
{
echo 'Calling ', __METHOD__, '() with arguments ', $one, ' and ', $two, "\n";
}
public function __call($name, $arguments)
{
$map = [
'2testnew' => 'twotestnew',
];
$name = mb_strtolower($name);
if (isset($map[$name])) {
return call_user_func_array([$this, $map[$name]], $arguments);
}
throw new RuntimeException('Not found');
}
}
This could use many refinements but I hope you get the idea. You can test the above code with the variable functions syntax (for good or bad, the syntax doesn't apply to function definitions):
$page = new MyController();
$page->{'2testnew'}('Foo', 'Bar');
It seems like your function name is invalid. Function names in php cannot start with a number. You can read more here.

calling a php namespace with a variable

I'm learning to use the namespaces in php, and I am trying to put a variable in the namespace name when calling a constant.
Here is my code.
fruits2.php
<?php
namespace fruits\red;
const redfruit = 'tomato';
fruits1.php
<?php
namespace fruits;
require_once('fruits2.php');
const myconst = 'banana';
echo myconst; // displays banana
echo '<br>';
echo \fruits\red\redfruit; // displays tomato
echo '<br>';
$color = 'red';
echo \fruits\$color\redfruit; // Parse error: syntax error, unexpected '$color' (T_VARIABLE), expecting identifier (T_STRING)
I don't understand how I can call the constant in this last line. I tried with the following but it is considered as a simple string.
echo '\fruits\\'.$color.'\\redfruit';
I'm pretty sure that I should be able to do it, because I could do something very similar when calling a class in another part of this code:
$name = '\fruits\basket\\'.$color.'\\eat';
$c = new $name(); //this works
Anybody knows the answer to that? Thanks!
Use the constant keyword:
$name = constant("fruits\\$color\\redfruit");
You have to escape the slashes.
Also the name has to be fully qualified (relative to the root namespace).

Error in php class with predefined values?

In my PHP file I have created a class as below but I am getting error on line 3rd and 5th line.
class CommonPath{
var $baseurl = 'http://mysite.com/';
var $docroot = realpath(dirname(__FILE__));
var $root = '/';
var $images = $this->root.'/img';
}
My Dreamwaver CS5 showing these lines (3rd & 5th) as erroneous lines and I am getting following error on executing this code.
Parse error: parse error, expecting `','' or `';'' in D:\wamp\www\site\libs\CommonPath.php on line 3
You can have only literals and constants as default values. No functions or other expressions are allowed.
There are two different mistakes. First, you cannot use functions to define class variables (line 3). Moreover, $this does not make sense in line 5, as you have got no object yet.
You can't assign the values like that right when you're declaring your member properties. Assign it in the constructor
class CommonPath{
var $baseurl = 'http://mysite.com/';
var $docroot = '';
var $root = '/';
var $images = '';
function __construct() {
$this->docroot = realpath(dirname(__FILE__));;
$this->images = $this->root.'/img';
}
}
You can not concat string and assign any value to variable which need to call any function, at the time declaring class variable.

Dynamic static method call in PHP?

Please could someone experienced in PHP help out with the following. Somewhere in my code, I have a call to a public static method inside a non-instantiated class:
$result = myClassName::myFunctionName();
However, I would like to have many such classes and determine the correct class name on the fly according to the user's language. In other words, I have:
$language = 'EN';
... and I need to do something like:
$result = myClassName_EN::myFunctionName();
I know I could pass the language as a parameter to the function and deal with it inside just one common class but for various reasons, I would prefer a different solution.
Does this make any sense, anyone? Thanks.
Use the call_user_func function:
http://php.net/manual/en/function.call-user-func.php
Example:
call_user_func('myClassName_' . $language . '::myFunctionName');
I think you could do:
$classname = 'myClassName_' . $language;
$result = $classname::myFunctionName();
This is called Variable Functions
I would encapsulate the creation of the class you need in a factory.
This way you will have a single entry point when you need to change your base name or the rules for mapping the language to the right class.
class YourClassFactory {
private $_language;
private $_basename = 'yourclass';
public YourClassFactory($language) {
$this->_language = $language;
}
public function getYourClass() {
return $this->_basename . '_' . $this->_language;
}
}
and then, when you have to use it:
$yourClass = $yourClassFactoryInstance->getYourClass();
$yourClass::myFunctionName();
As temuri said, parse error is produced, when trying '$className::functionName' :
Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM ...
In my case (static method with 2 arguments), best solutions is to use call_user_func_array with 2 arrays (as suggested by nikc.org):
$result = call_user_func_array(array($className, $methodName), array($ard1, $arg2));
BR
although i think the way you deal is a very bad idea, i think i may have a solution
$className = 'myClassName_'.$language;
$result = $className::myFunctionName();
i think this is what you want
You can easily do next:
<?php
class B {
public static $t = 5;
public static function t($h) {
return "Works!" . $h;
}
}
$g = 't';
$class = 'B';
echo $class::$g('yes'); //Works! Yes
And it will works fine, tested on PHP 5.2 >=
As far as i could understand your question, you need to get the class name which can be done using get_class function. On the other hand, the Reflection class can help you here which is great when it comes to methods, arguments, etc in OOP way.
Solutions like:
$yourClass::myFunctionName();
will not work. PHP will produce parse error.
Unfortunately, the only way is to use very slow call_user_func().
I know it's an old thread, but as of PHP 5.3.0 you should be using forward_static_call
$result = forward_static_call(array('myClassName_EN', 'myFunctionName'));
Using your $language variable, it might look like:
$result = forward_static_call(array('myClassName_' . $language, 'myFunctionName'));

Proper syntax for substituting in php?

Beginner question.
How do I substitute:
$_SESSION['personID'] for {personID} in the following:
public static $people_address = "/v1/People/{personID}/Addresses"
look this:
$template = "/v1/People/{personID}/Addresses";
$people_address = str_replace('{personID}', $_SESSION['personID'], $template);
echo $people_address;
output:
/v1/People/someID/Addresses
EDIT: This answer no longer applies to the question after edit but I'm leaving it around for a little while to explain some questions that occured in comments another answer to this question
There are a few ways - the . operator is probably the easiest to understand, its entire purpose is to concatenate strings.
public static $people_address = "/v1/People/".$_SESSION['personID']."/Addresses";
//PHP Parse error: syntax error, unexpected '.', expecting ',' or ';'
public static $people_address = "/v1/People/$_SESSION[personID]/Addresses";
//PHP Parse error: syntax error, unexpected '"' in
However you can't use concatenation in property declarations sadly - just simple assignment. You cant use the "string replacement" format either:
To work around it you could assign the static outside of the class - i.e.:
class test {
public static $people_address;
// ....
}
// to illustrate how to work around the parse errors - and show the curly braces format
test::$people_address = "/v1/People/${_SESSION[personID]}/Addresses";
// another (much better) option:
class test2 {
public static $people_address;
public static function setup() {
self::$people_address = "/v1/People/".$_SESSION['personID']."/Addresses";
}
}
// somewhere later:
test2::setup();

Categories