On the PHP documentation page for arrays, the example code given is the following:
<?php
$array = array(
"foo" => "bar",
"bar" => "foo",
);
// as of PHP 5.4
$array = [
"foo" => "bar",
"bar" => "foo",
];
?>
Does that mean that the first code is invalid in PHP 5.4, or is the second code just an alternative?
The first code is still valid. The second notation is just a shorter and more convenient alternative.
As others noted the first one is valid. The second one is shorter version.
Here are the pros and cons for second version:
Pro
Good for framework development when dealing with long parameterlists
Other web languages have similar syntax
Readable
Contra
Yet another alias
Would take distinctness from []
Not searchable through search engines
Unreadable
Patch may be difficult to maintain in future
from PHPWiki
Related
Let me just jump directly into my problem.
The Build-up
I have some simple language files which just return an associative array containing the language strings (This is Laravel if that's of any help). Don't worry about the variable, that's just for demonstrational purposes.
lang/en/common.php:
<?php return [
"yes"=>"Yes",
"no"=>"No",
"hello"=>"Hello {$name}!",
"newstring"=>"This string does not exist in the other language file",
"random_number"=>"Random number: ".rand(1,10)
];
lang/da/common.php:
<?php return [
"yes"=>"Ja",
"no"=>"Nej",
"hello"=>"Hej {$name}!"
];
Now, as you can see, the index newstring doesn't exist in the danish language file. Instead of having to remember to add all the indexes all the language files instead of just one, I wrote a script, which basically does this:
$base_lang = require('lang/en/common.php');
$language_to_merge = require('lang/da/common.php');
$merged_lang = array_replace_recursive($base_lang, $language_to_merge);
file_put_contents('lang/da/common.php', var_export($merged_lang, true));
The problem
So far, so good. Now, lets say that $name = "John Doe";. By the very nature of PHP, after running this script the lang/da/common.php will now be
<?php return [
"yes"=>"Ja",
"no"=>"Nej",
"hello"=>"Hej John Doe!",
"newstring"=>"This string does not exist in the other language file",
"random_number"=>"Random number: 4"
];
As you might have guessed, the unwanted result is in the hello and random_number-indexes. Preferably it should still be "hello"=>"Hej {$name}!" and "random_number"=>"Random number: ".rand(1,10), but obviously that ain't happening due to PHP parsing the array values, which basically tells me that this is the wrong strategy.
Wanted result:
<?php return [
"yes"=>"Ja",
"no"=>"Nej",
"hello"=>"Hej {$name}!",
"newstring"=>"This string does not exist in the other language file",
"random_number"=>"Random number: ".rand(1,10)
];
The "how the h.. do I do that?"
Any idea how to get around this? I could file_get_contents() and do some regex, but i worry that there's too many error sources involved in that.
Thanks in advance!
EDIT
Some people have recommended using single quotes. While that actually answers my question, I became aware that I wasn't precise enough; when the Language class treats the files, I want the values to be parsed (the normal behaviour) - but only when I run my merge-script I want the actual literal variable references to remain intact.
EDIT 2 - Temporary workaround
Until I find a proper solution for this, I'm just running through the arrays of the base language, checking for key existences in the language I'm trying to fill with the missing keys - and appending a comment to the bottom of those files.
Edit: See OP's comment. This is true, but not the answer to his question :)
You should use single quotes instead of double quotes:
<?php return [
"yes"=>'Yes',
"no"=>'No',
"hello"=>'Hello {$name}!'
"newstring"=>'This string does not exist in the other language file'
];
PHP only parses variables inside double-quotes.
I'm not a usual php user but till now I always used to declare arrays in this way:
$arr = ["id" => 15,"val" => 13];
In my local xampp (PHP Version 5.5.9) environment this worked fine, but on server (PHP Version 5.3.28) this code fails giving:
PHP Parse error: syntax error, unexpected '[' in /web/htdocs/site.sit/home/pdo.php on line 24
I switched the declaration to this and everything is ok,
$arr = array("id" => 15,"val" => 13)
But I want to understand why this error occurred
As documentation states it is not a matter of deprecated code and I see that the first example is using my first array declaration with the comment note
// as of PHP 5.4
What does it means?
Anyway I suspect that its a problem related with some sort strict mode.
array() has always been the way to declare arrays in PHP since before the dawn of time. In PHP 5.4, the shorter [] has been introduced, simply because it's shorter and many other languages use it too. [] doesn't work in 5.3 or below. TFM documents that.
When writing the syntax for an associative array in PHP we do the following
$a = array('foo' => 'bar');
I am curious of the relationship of the => syntax, or possibly operator. Does this relate to some kind of reference used in the hash table in ZE, or some kind of subsequent right shift or reference used in C? I guess I am just wondering the true underlying purpose of this syntax, how it relates to ZE and/or php extensions used to handle arrays, how it possibly relates to the written function in C before compiled, or If I just have no idea what I am talking about :)
The => symbol a.k.a. T_DOUBLE_ARROW is just a parser token like class, || or ::.
See: The list of php parser tokens
It's nothing special apart from that fact that "it looks like an arrow" and it is used for "array stuff".
Of course the exact usage is more complicated than that but "array stuff" is the short inaccurate description that should do it.
It's used to represent key => (points to) value
The answer to that is no simpler than "It looks like an arrow".
It's not exactly the assignment operator per say because that would mean a variable-like assignment (like for the array itself). This is an array-internals specific assignment operator.
Webdevelopers are cool like that :P
PHP would be a lot cooler if you could write things like this:
$array = [2, 3, 5];
$object = { "name" : "Harry", "age" : 23, "cats" : ["fluffy", "mittens", "whiskers"]};
but, I just spent a lot of time looking for an extension (even an experimental alpha or anything) adding json syntax to PHP but found nothing.
Does anything like this exist?
If not, considering the existence of json_decode() and facebook's XHP, would it be difficult to write an extension to do this?
I have no experience writing PHP extensions, although I did a lot of C in college.
You could just wrap your datastructure in json_decode and be done with it:
$array = json_decode('[2, 3, 5]');
$object = json_decode('{
"name" : "Harry",
"age" : 23,
"cats" : [
"fluffy", "mittens", "whiskers"
]
}');
Yes, it doesn't do typechecking until the statement is executed, and you'll have a bit of a problem handling multiple quotes, but you could always use a HEREDOC for that.
Different syntax for PHP arrays has been proposed and rejected many times before.
Unfortunate, I know, because I hate the ugly syntax too.
Update: All the below has become somewhat moot with PHP 5.4; we now have [..] array syntax.
Yes, PHP's array syntax is overly verbose and ugly and I too wish it would be more terse.
No, it would probably not be a good idea to attempt to change that for existing versions of PHP, since it's a feature that would need to be baked into the parser. That means your PHP applications would only run on custom compiled versions of PHP, which makes your app much less portable and thereby negate one of the good things about PHP.
You may want to attempt something like a compiler, which compiles your custom array syntax into normal syntax before running the code. If you went that far though, using an entirely different language to begin with may be the better choice.
Try to lobby for a Javascript-like syntax for PHP 6.x. Until then, just write array(). :)
If you want to write something that isn't PHP, then use something that isn't PHP. Otherwise, use array().
$array = array(2, 3, 5);
$object = array('name' => 'Harry', 'age' => 23, 'cats' => array('fluffy', 'mittens', 'whiskers'));
A mixture of associative and numerically indexed arrays usually gets you pretty close:
$object = array("name" => "Harry", "age" => 23, "cats" => array("fluffy", "mittens", "whiskers"));
In my opinion (especially because of the existence json_encode) it's not meaningfully different to write straight JSON over something like the above.
php doesn't handle json - whiwch is why it gives you the tools to encode/decode.
I you are desperate to 'write' in that manner just stick quotes around it:
$object = '{ "name" : "Harry", "age" : 23, "cats" : ["fluffy", "mittens", "whiskers"]}';
As far as php is concerned a 'json object' is nothing more than a string...
As people have said above, different languages have different syntax - if you don't like PHP's syntax, you might consider considering other languages.
JSON stands for "javascript object notation" - maybe what you want is server-side javascript. There's a huge array of server-side javascript options out there - jsgi/jack (narwhal), ringojs, flusspferd, node.js, v8cgi, etc. etc. http://wiki.commonjs.org/
If php would be a lot cooler and would just let you write things like this, it would be JavaScript, I guess;) but serious:
My approach for that problem is to load json files (Get data from JSON file with PHP) and just decode them.
Maybe you could also use a build tool like Grunt/Gulp and stringyfie and inject seperate json-files in your php code. (https://florian.ec/articles/buliding-symfony2-with-gulp/)
I am working on a small parser that should accept input in a number of languages. I am going to have maybe 50 strings that will serve as keywords/anchors in parsing the input. In PHP, what would be the best way to organize these translated keywords?
One possible solution that comes to my mind is to use an associative array. Like this:
$lang = array('us' => array('totalDebt' => 'Total Debt', 'color' => 'Color'),
'gb' => array('totalDebt' => 'Total Debt', 'color' => 'Colour'))
which I could then access using the following:
$langCode = 'en';
$debtPos = strpos($lang[$langCode]['totalDebt']);
Are there any better, proven methods for dealing with a bunch of short strings translated into a bunch of languages?
For a complete translation solution, you can look on a solution like gettext.
you solution is good enough (fast, cheap on resources) for small dictionaries.
I didn't understand what you tried to do using the strpos() function.
Don't forget to use some kind of fallback if the term you want to translate doesn't exists in the language, usually the fallback is to the English.
Generally people use l10n (or something similar) in their application because it allows for additional languages by adding a localization file which means the programmers do not have to change code. But if it is a simple script, then full on localization would be overkill.
I have seen your solution used in other OS projects, however the $lang array is usually constructed in different files. For example:
<?php // lang.us.php
$LANG['us'] = array(
'totalDebt' => 'Total Debt',
'color' => 'Color',
);
and so on for lang.gb.php, lang.de.php, etc.
As Peter said, you've got the right idea, but separate your languages into different files. It means that PHP won't have to store the array of every single word in every single language. Because you only are going to be loading one language at a time, you can skip the $lang['us'] level of nesting too.
You could even "extend" languages:
<?php // lang.en-gb.php
$lang = array(
'color' => "Colour",
'totalDebt' => "Total Debt",
...
);
?>
<?php // lang.en-us.php
include('lang.en-gb.php');
$lang['color'] = "Color";
// don't need to redefine "totalDebt"
?>
You might even consider creating a basic class which handles all this for you: detect the locale, choose the correct file, have "error" handling, if a term isn't defined in a particular language, etc.
You probably don't want 'totaldebt' => 'Total Debt' as that will ultimately obfuscate your code, and is slower than just storing 'Total Debt' as the hash key. The gettext way of doing things is to just wrap the strings in a function.
so rather than:
echo "Color";
You do:
echo t("Color");
the t() function will look at the globally defined language, and make the substitution if possible. At some point, you may want to use gettext and doing it this way will be compatible.