Dynamic PHP object access differs on local and server - php

On an local XAMPP development environment I can access an object's property in PHP by calling:
$xmltemplates->$_POST['xmlmap']->sheet;
But on a live server I have to put the POST variable into a string so it works:
$gehmiraufdiekeks = $_POST['xmlmap'];
$xmltemplates->$gehmiraufdiekeks->sheet;
Do I need to fix alle the code or could it be a server configuration issue?
UPDATE:
I expected the XAMPP test environment to be at least PHP 7. So I only checked the server's PHP version which was 7. But when I doubled checked both PHP Infos, my local PHP version was 5.6. D'oh! So anyone who has this kind of problem: please update your code to PHP 7. ;)

Two things:
Production servers are configured (or should be) to hide error messages. That's why you're getting none. You need to either check the server logs or enable full error reporting.
I understand you refer to invoking variable properties without using curly braces, as in:
$key = 'bar';
var_dump($foo->$bar);
... rather than:
var_dump($foo->{$bar});
That's explained in the Changes to the handling of indirect variables, properties, and methods section of the PHP/7.0 migration guide (emphasis mine):
Indirect access to variables, properties, and methods will now be evaluated strictly in left-to-right order, as opposed to the previous mix of special cases.[...]
Code that used the old right-to-left evaluation order must be rewritten to explicitly use that evaluation order with curly braces (see the above middle column). This will make the code both forwards compatible with PHP 7.x and backwards compatible with PHP 5.x.

Actually, this is PHP version related. They changed this in PHP 7 so no one can mess up your script with a wrecked, unescaped string sent via POST forms.

Related

PHP Notice: Only variables should be assigned by reference

I am getting the following error.
PHP Notice: Only variables should be assigned by reference in
/var/www/html/plugins/system/jxtcadminlock/jxtcadminlock.php
I am usig PHP 7.2
And the 39th line of the file(/var/www/html/plugins/system/jxtcadminlock/jxtcadminlock.php) is as below.
$mainframe =& JFactory::getApplication('admin');
I need to fix this without upgrading joomla.
First of all, this is just a notice. If you aren't going to fix your codebase manually to make it PHP/7 compliant you can just ignore it.
If I'm not wrong that's the old PHP/4 syntax, obsoleted in 2004, to deal with the fact that objects used to be passed by value rather than reference. It's quickly mentioned in the Migrating from PHP 4 to PHP 5.0.x guide.
Since PHP/5 you can drop the & sign altogether. However, it's very likely that this isn't the only compatibility issue.

Get actual PHP runtime programmatically

I have a script which would need to understand whether it runs under HHVM or the standard Zend engine.
Using zend_version() outputs different version tags - 2.5 for PHP5 and 2.4.99 for HHVM master as of current, and I don't feel safe using this method at all due to potential overlaps.
Using phpversion() just gives me the supported PHP version, again I don't see this as safe due to potential overlaps.
What would be the best way to safely determine exactly which runtime the script is executing on?
I might suggest testing for the actual behavior itself, not what platform you're using. Even if you can determine whether you're running PHP or HHVM, you'll end up needing to know the precise version once either PHP or HHVM fixes / changes this behavior. You can use e.g. the code in this GitHub comment and compare its output to test which type of behavior your platform exhibits.
This is the code which can distinguish the behaviors:
<?php
function start_elem($parser,$name,$attribs) {
echo "<$name>";
}
function end_elem($parser,$name)
{
echo "</$name>";
}
$parser=xml_parser_create();
xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
xml_set_element_handler($parser,"start_elem","end_elem");
$buf = '<F>';
echo xml_parse($parser,$buf,strlen($buf)==0);
Alternatively, you could also just use the answer to this question, which indicates that HHVM defines HHVM_VERSION whereas PHP (obviously) does not, so you can use that to determine the runtime.

Can't access model data using Model name in CakePHP 2.x with PHP version 5.3.27

On my development server, I installed PHP (5.5), MySQL and Apache. The hosting company only supports up to PHP version 5.3.27. I don't really work in PHP, often so I might be missing something obvious here, but my problems are the following:
CakeSession::read('User.stuff')['more_stuff']; // works on 5.5
CakeSession::read('User.stuff')['more_stuff']; // syntax error on 5.3... wat?!
I managed to fix the above issue by assigning CakeSession::read('User.stuff') to a temp variable, and then accessing more stuff with $tmp['more_stuff'].
However, I have a bigger problem. I can't seem to access model names by their model name in arrays returned from databases. Namely, the following code stopped working:
$some_model['ModelName']['model_field']; //works on 5.5
$some_model['ModelName']['model_field']; //warning about 'ModelName' being a non-existant index.
When I try $some_model[0]['model_field'] it works just fine.
Cheers!
EDIT: Ok, turns out < PHP 5.4 doesn't support subscripting return values. Still weird, but it explains the first problem.
As you found out, array dereferencing with function/method call expressions is only supported as of PHP 5.4, nothing special about it, it's simply a feature of newer PHP versions.
Your other problem is most probably not that string indices magically don't work anymore, but simply that the structure of the array you are accessing is different.
Where this difference might stem from? Pretty hard to tell without any context. You should provide some code that can be used to reproduce your situation, and you should also do some more debugging on your own, trace back the function call flow and check at which point the data becomes different.

PHP strange error messages

I have created a website 3 month ago. I uploaded it to internet and it worked(it still works there). Now I installed it in my local computer and trying to access it. However it prints the following error messages multiple times:
Deprecated: Assigning the return value of new by reference is
deprecated in C:\xampp\htdocs\ptr\xajax\xajax_core\xajax.inc.php on
line 1258
Strict Standards: Only variables should be assigned by reference in
C:\xampp\htdocs\ptr\xajax\xajax_core\xajaxPluginManager.inc.php on
line 269
I am using XAJAX framework and the errors have something to do with this framework. Since I haven't changed anything in the library files, I don't understand what the problem can be. Please help... I am freaking out
The framework you are using seems to be a little bit outdated and uses such constructs
$x = & new Classname();
The & before new is deprecated since PHP 5.0 (which is several years old now). With the introduction of E_DEPRECATED- and E_STRICT-messages it throws such a message now.
Unfortunately this kind of statement are deprecated from PHP 5. In your local machine you're running a version which is 5.3 while your server is running an older version. Thus, on your machine is thrown a E_STRICT error. To avoid this problem, you have to change lines like:
$node_obj =& new someClass($somearg, $moreargs);
into
$node_obj = new someClass($somearg, $moreargs);
Xajax 0.6 targets this and a couple of other issues. When the development on xajax 0.5 started many users were still trapped on PHP4 Webservers and this syntax helped maintain compatibility for PHP4 up to 5.2.x.
Xajax 0.6 can be found on https://github.com/Xajax/Xajax-Project
Though it's still beta, it's already pretty solid. Many deprecated function were dropped and the core was shrinked & optimized.
Previous comments fully explain the source of those warnings. Your website will work fine despite of them. But you can disable PHP error reporting, if you want to hide these messages - this manual may help you: http://complete-concrete-concise.com/web-tools/how-to-turn-off-display_errors-in-xampp
(UPD: For your local version only of course)

PHP: Code checker since PHP is a loose type / dynamic language?

I have a small PHP web-based application that is beginning to grow moderately in size.
I'm starting to become concerned with managing my PHP code base, given PHP is a loosely/weak typed, dynamic language.
How do others manage their code based for loosely/weak typed, dynamic languages?
Do pre-parsers exist for PHP that allow me to runs checks on my code base to identity such things like below?
$var1 = 'data';
// vr1 doesn't exist, it's a typo of $var1, but PHP would allow for this and not complain
echo $vr1;
UPDATE:
The example above might not be the best example but essentially, what I'm trying to convey is that certain errors in a dynamically weak typed language would only be found when the code is run in production at RUN TIME; whereas, some of these issues would typically be found in strongly typed static languages at COMPILE time.
How can I also find these non-algorithm type of errors in PHP prior to moving my code into production without having to create an insane number of Unit Tests?
As such, does anything exist where I can run my PHP code through it, prior to moving into production, and this pre-processor parses my code to ensure I'm only using defined variables, etc. Essentially, check my code for validation for non-algorithmic type of uses. E.g. not trying perform algebra on a string, etc.
UPDATE 2
Please note, this question is still not answered because I'm looking for a way to identity these type of non-algorithmic errors in PHP at "compile" type, not RUN TIME.
You can lint your PHP with php -l filename.php. This would show any syntax errors.
There is IDEs out there that will lint while you write the code. Those usually can also detect issues like shown in your question in addition to linting.
Apart from this, consider writing UnitTests for your code to ensure functionality and have a look at http://phpqatools.org for a number of other tools that can assist you in increasing code quality.
Make sure you have error_reporting(-1); set during development to enable all errors, in addition to enable display_errors and display_startup_errors in php.ini. Disable the latter two on your production system to prevent exposure of server information.
Edit after update: PHP source code is compiled on-the-fly. PHP's compile time is effectively at run time. If you want compiled PHP, you have to use Facebook's HipHop.
PHP will definitely complain about that with either a warning or a notice if you set your error_reporting config directive appropriately.
See:
http://us2.php.net/manual/en/errorfunc.configuration.php#ini.error-reporting
Runtime Errors
Uninitialized variables are runtime errors (of level E_NOTICE) in PHP, so you can only see them at runtime. The example you gave may or may not end up erroring, depending on how the code is executed. For instance, it could be that $vr1 is defined in a conditional include() that is sometimes included and sometimes not.
Additionally, it's possible to dynamically create variables at runtime using variable variables ($$var), so again that $vr1 may actually be defined somewhere. If the PHP interpreter failed to run valid syntax, or gave compiler errors on valid syntax, that would be a different sort of problem.
You might compare the uninitialized variable circumstance to a divide by zero error. It's not an error unless it actually happens.
Compiletime errors are E_PARSE, E_COMPILE_ERROR, or E_COMPILE_WARNING (not fatal) in PHP. These include things like missing files, functions, or classes, i.e. trying to execute code that isn't there—something PHP can't possibly do. If PHP may be able to, it will try.
Detection and Prevention
At the very least, you should make sure that your development and testing environments have all of the PHP error junk turned on in the ini:
error_reporting = E_ALL|E_STRICT
display_errors = On
Or at runtime:
error_reporting(-1);
Self Discipline
A few tips for working with PHP that might help:
Use functional programming
Establish code smells and write clean syntax
Do your own type checking (OOP and functional programming can make this easier)
Avoid the global scope and include()-based control structures
Use an IDE with code awareness aids, like Netbeans.
For instance, in your example above, if you have to pass your variable into a function or method that checks that the parameter isset() or !== nullbefore using it, you can avoid or mitigate the problem of uninitialized variables.
Resources
Comparison operators (see Identity, specifically)
Type comparison tables
is_int(), is_float(), etc.
That type of error would be caught if you set error reporting to the max. It would give a Notice indicating that $vr1 wasn't set.
You can set error reporting in your php.ini file, or on individual pages using the ini_set() function.
The closest thing is php's lint checker, but that's more of a syntax checker. You can run lint from a command line:
php -l path/to/file.php
You could build this into your file repository system by setting up a pre-commit check.
As PHP is not usually considered to go through a separate COMPILE process perhaps you could explain at what point you consider your code to be COMPILED?
Here's another SO question that focuses on PHP code analysis tools.
Hack is a statically typed language created by Facebook which is essentially PHP with many features added and removed.
PhpStorm is an IDE which provides "inspections" which catch many things that would be caught by a static type checker, such as the undefined variable in your example.
I started writing a static type checker for PHP here based on PHP7 type hints and PHPDoc annotations. I never finished it but there are some passing tests and the design so far seems to be sound.

Categories