I want to have a string variable for a PHP class, which would be available to all methods.
However, this variable is quite long, so I want to separate it into multiple lines.
For example,
$variable = "line 1" .
"line 2" .
"line 3";
But above doesn't work.
I tried EOD, but EOD is not allowed within class. And when I declare it outside the class, I can't access the variable from within the class.
What is the best way?
If you are using PHP >= 5.3, you could use HEREDOC syntax to declare your string :
class MyClass {
public $str = <<<STR
this is
a long
string
STR;
}
$a = new MyClass();
var_dump($a->str);
But this :
is only possible with PHP >= 5.3
and the string must not contain any variable
this is because the string's value must be known at compile-time
which, btw, explains why the concatenation, with the ., will not work : it's done at execution time.
And another drawback is that this will put newlines in the string -- which might, or not, be a bad thing.
If you are using PHP <= 5.2 :
You can't do that ; a solution could be to initialize the string in your class' constructor :
class MyClass {
public $str;
public function __construct() {
$this->str = <<<STR
this is
a long
string
STR;
}
}
(same not with newlines)
Or, here, you can do strings concatenations :
class MyClass {
public $str;
public function __construct() {
$this->str = 'this is' .
'a long' .
'string';
}
}
(this way, no newlines)
Else, you can have a string that's surrounded by either single or double quotes, and put it on several lines :
class MyClass {
public $str = "this is
a long
string";
}
(Here, again, you'll have newlines in the resulting string)
$var = "this is a really long variable and I'd rather have it " .
"span over multiple lines for readability sake. God it's so hot in here " .
"can someone turn on the A/C?";
echo $var;
Which outputs:
this is a really long variable and I'd rather have it span over multiple lines for readability sake. God it's so hot in here can someone turn on the A/C?
What you have now works using the string concatenation operator. If you can post more information regarding your issue, some code or perhaps a further explanation of how it doesn't work. More information will lead you to a better answer.
I'm using PHP 5.5.9 and have come across a similar issue only with class constants. I want to use a somewhat long string as a constant but I don't want:
really long lines of code
newlines showing up in the text at the break points
the property to be mutable
the property to be inaccessible outside the class
I think the solution here is something that is done a lot in the Laravel 5 scaffolding and why they kept doing this had me baffled until now. What they do is something like:
public static function getLongPropertyString()
{
return 'A a string that can be arbitrarily long and contain as ' .
'many breaks in the code as you want without line breaks ' .
'appearing in the resulting string.';
}
This method provides an immutable string. You don't strictly get that by creating a protected/private variable with getters since its still mutable internally. Only changing the code or overriding can change this string. Another pro is that making it static allows a single "instance" per class.
Unfortunately, now your code would be Class::getProperty() rather than just Class::property. Another downside is that the concatenation would be done every time you call the function but depending on how you use this, that cost is typically negligible.
It would be cool if the PHP compiler were able to recognize that the concatenation operation on only values already known at compile time can be run at compile time and the result substituted (beings more knowledgeable than myself know why this is so).
Related
I'm running PHP 5.5.9 and I'm getting a parsing error that I haven't a clue how to resolve. Here's an extremely contrieved example of the technique I'm trying to employ:-
<?php
class NumberDisplayer {
var $numbers = [];
function __invoke($n) {
array_push($this->numbers, $n);
return $this;
}
function display() {
foreach ($this->numbers as $number) {
echo "$number, ";
}
}
}
((new NumberDisplayer())
(5)
(10)
(14)
(20)
(11)
->display());
?>
That yields:-
Parse error: syntax error, unexpected '(' in <documents>/index.php on line 18
Such a pointless example could obviously be solved via better means, but my question is how to make this technique work in situations where it's a good fit.
My reasoning is as follows: new NumberEchoer() evaluates to an instance of NumberEchoer, which itself is callable due to __invoke. Because of this, I should be able to invoke the expression, which itself returns $this which is also invokable, and so on and so forth. At the end of the expression, I invoke the display method which does the displaying.
I also tried to pack the whole expression onto a single line, but the elimination of the newlines didn't fix anything.
I seem to be able to store NumberDisplayer into a variable and invoke the variable manually on every line, but it makes the code far less readable.
How can this idiom of chaining magic methods be done in a readable fashion?
1.. Remove the var because php variables uses $, example $numbers = " ";
2.. Use only one underscore for the invoke name like __invoke.
3.. Edit echo "$number,"; to echo $numbers; as ur empty array in the loop array
Having this 2 classes:
class run {
public static $where = "there";
}
class there {
public static $place_name = "A beautiful place..";
}
To get place_name I can do this:
$place = "there";
echo $place::$place_name;
But I might want to do something like this at some point..:
echo {$run::$where}::$place_name;
Obviously, the last snippet doesn't work.
Is there any way to make it do work?
If you do not want to use a variable (as you said in a comment), think twice. Variables are cool in PHP, very fast and just the needed glue to work-around its limited parser (which of it was said makes PHP quite fast). So why not use a variable here? It's easy to type and quickly done.
If you don't want the variable and as we already have found out that PHP's syntax is limited, you can at least write a one-liner with PHP 5.4+ to achieve what you're looking for:
echo (new ReflectionClass((new ReflectionClass($run))->getStaticPropertyValue('where')))->getStaticPropertyValue('place_name');
which then finally should make visible that using a variable is more comfortable:
echo (unset) $place = $run::$where, $place::$place_name;
Demo: http://eval.in/13942
My reading of the manual (the bit just before the section heading "String access and modification by character") is that you can do some fancy tricks with class constants and {} inside a string but you can't do the simple thing that would make this method return the truth:
class c {
const k = '12';
public function s() {
return "Twelve in decimal is {c::k}.";
}
}
Is the right solution here to concatenate?
Is the right solution here to concatenate?
Yes. The extended curly syntax doesn't support it.
Alternatively, you could export the list of constants to an array and use it (or export the constant to a single scalar variable name), but that's not really a good solution IMO.
Note that constants are available, as you can do this:
const k = 'foo';
$foo = 'bar';
echo "{${c::k}}"
giving you bar, but that's not what you want.
It's a little cryptic, but there is a note on this in the manual.
Functions, method calls, static class variables, and class constants inside {$} work since PHP 5. However, the value accessed will be interpreted as the name of a variable in the scope in which the string is defined. Using single curly braces ({}) will not work for accessing the return values of functions or methods or the values of class constants or static class variables.
The last sentence tells you it won't work so yes, concatenation is the way to go here.
(modified) Example of above paragraph:
<?php
class beers {
const softdrink = 'rootbeer';
}
$rootbeer = 'A & W';
// This works; outputs: I'd like an A & W
echo "I'd like an {${beers::softdrink}}\n";
// This won't work; outputs: I'd like an {beers::softdrink}
echo "I'd like an {beers::softdrink}\n";
The curly syntax only works for 'variable expressions'. And you need anything that you can access with {$.
Oh, there's only that workaround:
$c = "constant";
return "Twelve in decimal is {$c('c::k')}.";
Which is obviously not much shorter or more readable than just using string concatenation here.
This prints apple:
define("CONSTANT","apple");
echo CONSTANT;
But this doesn't:
echo "This is a constant: CONSTANT";
Why?
Because "constants inside quotes are not printed". The correct form is:
echo "This is a constant: " . CONSTANT;
The dot is the concatenation operator.
define('QUICK', 'slow');
define('FOX', 'fox');
$K = 'strval';
echo "The {$K(QUICK)} brown {$K(FOX)} jumps over the lazy dog's {$K(BACK)}.";
If you want to include references to variables inside of strings you need to use special syntax. This feature is called string interpolation and is included in most scripting languages.
This page describes the feature in PHP. It appears that constants are not replaced during string interpolation in PHP, so the only way to get the behavior you want is to use the concatenation that Artefacto suggested.
In fact, I just found another post saying as much:
AFAIK, with static variables, one has
the same 'problem' as with constants:
no interpolation possible, just use
temporary variables or concatenation.
Concatenation has been suggested as the only solution here, but that doesn't work when using syntax like:
define("MY_CONSTANT", "some information");
$html = <<< EOS
<p>Some html, **put MY_CONSTANT here**</p>
EOS;
Of course, the above just puts the text 'MY_CONSTANT' in $html.
Other options include:
define a temporary variable to hold the constant:
$myConst = MY_CONSTANT;
$html = <<< EOS
<p>Some html, {$myConst} </p>
EOS;
if there are many constants, you can get an array of them all and use that:
$constants = get_defined_constants();
$html = <<< EOS
<p>Some html, {$constants["MY_CONSTANT"]} </p>
EOS;
Of course, in such a trivially short example, there's no reason to use the <<< operator, but with a longer block of output the above two may be much clearer and easier to maintain than a bunch of string concatenation!
The question was already answered, but I'd like to provide a more generic insight on this.
In double quotes, PHP recognizes anything starting with a $ as a variable to be interpolated. Further more, it considers array and object access ([] and ->) but only up to a single level. E.g. "$foo->bar" interpolates $foo->bar and $foo->bar->baz does the same thing and treats ->baz as a string literally. Also, the quotes in [] must be ommited for string keys. E.g. "$foo[bar]" interpolates $foo['bar'] while "$foo['bar']" is a syntax error. AFAIK, that's it. To get more functionality, you need the "{$...}" syntax.
The $ here is actually a part of the syntax and it doesn't work without it. E.g. "{FOO}" will not interpolate a constant FOO, it's simply a syntax error. However, other than some strange syntactical restrictions, this construct is actually quite strong and may contain any valid PHP expression, as long as it starts with a $ and is an array access, object access, or a function call. (Maybe some other cases are permitted to. Please let me know, if anyone has a better understanding of this.) The most general solution to your problem would be to define something like the following function somewhere in your code base:
$id = function ($x) {
return $x;
}
It's simply the identity function - it returns whatever you give it. It must be defined as an anonymous function, so you can refer to it as $id with the $.
Now you can use this function to interpolate any PHP expression:
echo "{$id(CONSTANTS)}"
echo "{$id($some + $operators - $as . $well)}"
// etc...
Alternative for PHP versions < 5.3 where you can't use anonymous functoins:
class Util {
function id ($x) { return $x; }
}
$u = new Util;
echo "{$u->id(ANY + $expression . $here)}"
// or...
function id ($x) { return $x; };
$id = 'id';
echo "{$id(ANY + $expression . $here)}"
The native interpolation does not support constants. Still not up to PHP 8.2 (and maybe later on). An alternative to echo is to use printf() or sprintf() for getting the interpolation result as string.
const MY_CONSTANT = "foo";
printf("Hello %s bar!", MY_CONSTANT);
Hai. I was making this simple string class and was wondering if there was a more natural way of doing it.
class Str{
function __construct($str){
$this->value = $str;
$this->length = strlen($str);
..
}
function __toString(){
return $this->value;
}
..
}
so now i have to use it like this:
$str = new Str('hello kitty');
echo $str;
But that doesnt look very 'natural' with the parentheses. So i was wondering if something like this, or similar was possible.
$str = new Str 'hello kitty'; # I dont believe this is possible although this is preferred.
$str = new Str; # get rid of the construct param.
$str = 'value here'; #instead of resetting, set 'value here' to Str::$value??
In the second method, is there a way i could possibly catch that variable bing set again and instead of reseting it, set this to Str::$value ? I have thought around and the closest i could come up to is the __destruct method. but there was no possible way to know how it was being destroyed. Is this possible or am i wasting my time?
Since PHP is loosely typed, there is no natural string class, because the natural way of using strings is, well, by just using them. However, as of PHP5.3 there is an extension in the SPL that provides strongly typed scalars:
http://php.net/manual/en/book.spl-types.php
However, keep in mind that this extension is marked experimental and subject to change. As of now, it is also not available on Windows.
You might also want to try https://github.com/nikic/scalar_objects
This extension implements the ability to register a class that handles the method calls to a certain primitive type (string, array, ...). As such it allows implementing APIs like $str->length().
Also See: https://github.com/alecgorge/PHP-String-Class
A good string class
It's impossible to call functions in PHP without parentheses.
Your next method will change the reference to string.
Why it doesn't look natural to you? It's the same way in Java.
You may find this useful:
php-string
I'm afraid to tell you that you won't have any luck with either of both.
$str = new Str 'hello kitty'; will end up in fatal error and though the second method is valid it doesn't do what you intend but rather reassign a native string.
May I ask why you would want to have a wrapper araound a native type?