Removing var_dump from PHP code - php

We have a large codebase, and every so often a var_dump used for testing and not removed/commented suddenly appears out of nowhere. There is a messy solution using XDebug (http://devzone.zend.com/1135/tracing-php-applications-with-xdebug/), but maybe there's something ingenous that can be done in PHP at runtime.
Also, I don't want to modify or search code via regex. I've tried using my own var_dump_v2, but it falls out of use quickly.

Is it possible to use the disable_functions operation in php.ini to disable var_dump on your production server? I am not sure what the outcome of this setting is (ie does it fail with an error, or silently) the documentation is not so clear.
http://php.net/manual/en/ini.core.php - see "disable_functions"
Also there is override_function:
<?php
override_function('var_dump', '$a', 'return 0;');
?>
http://php.net/manual/en/function.override-function.php

There are actually ways to do this, if you have PECL available and runkit installed. You kan make runkit able to overide PHPs internal functions if you in php.ini set runkit.internal_override to "1".
For removing the var_dump function, you could use:
runkit_function_remove('var_dump');
In your case, not to get an error, you should probably instead use something like this:
runkit_function_redefine('var_dump', '','');
Take a look at the runkit extensions documentation here.
You may also want to take a look at "Advanced PHP debugger", another extension that seems to offer an override_function().

You can use monkey patching.
Just defines a namespace on the first line of your file and defines the function var_dump
<?php
namespace monkey;
function var_dump($obj) {}
Of course, it implies that you do not use a namespace in your current file
You could use the function var_dump() prefixing it with the root namespace(): \var_dump()
Of course, all others native function will continue to work as usual as long as you do not override them in your namespace.

Why don't you use serialize() or json_encode() if you have a large database? That will be very useful.
But take note, serialize() will give you a 1-line output somewhat like this:
's:0:"";s:5:"value";'
So you need to learn the anatomy of serialize() to use it: PHP Serialize

Related

Substitute for apc_exists()

I want to replace Apc_bc to APCU.
What I use Apc_bc now are just three function.
apc_exists()
apc_fetch()
apc_store()
then, now I found apcu_fetch() and apc_store().
However I can't find the substitute for apc_exists().
How can I solve it ??
Environment - PHP7.3.8
php.net contains a complete function list for APCU, which appears to closely reflect APC's (same function names, simply substituting apc with apcu).
The one you're looking for is (unimaginatively!) named apcu_exists.

Add removed/deprecated functions to PHP5

Is it possible to add a removed/deprecated function to PHP5? Like session_is_registered, ereg, etc.
[update] solved for session_is_registered:
<?php
function session_is_registered($name) {
return isset($_SESSION[$name]);
}
thanks.
Of course you can do it by modifying and recompiling the PHP source code, however the first question you have to answer is Do I really need to this or I might be better to go for my IDE's find-and-replace function?
If there is a real need for this -- for whatever reason, maybe you can redefine those functions. I haven't test it yet, as I agree with others that functions and features get removed or deprecated for a good and mostly important reasons, so I'm not sure if it does work in a situation that the function is removed or depreciated, but you can try to redefine them either using runkit_function_redefine or
override_function.
In that case you have to simulate the functionality again -- probably with their good-to-go replacements, so again think twice before start doing that.

How to mock built-in php socket functions?

I'm working on some code that reads from a socket, and it goes wrong when it gets a certain large input. I went to add a unit test for this, before fixing it, but got stuck because I cannot mock fread (and the other PHP built-in functions I'm using such as fsockopen, feof, etc.).
In simple terms my problem is that this code fails with "Fatal error: Cannot redeclare fgets() ...":
function fgets($fp){
return "xxx";
}
I realize I could create a socket wrapper class, that my real code uses, and then I could create a mock object for that wrapper class. But that is The Tail Wagging The Dog, and I can think of reasons it is a bad idea, beyond just the principle of the thing. (E.g. Making code more complex, efficiency, having to refactor code not under test yet.)
So, my question is how can I replace the built-in fgets() implementation with my own, within a unit test? (Or, if you want to think outside the box, the question can be phrased as: how can I control the string that a call to fgets($socket) returns, when $socket is the return value from a call to fsockopen?)
ASIDE
Installing apd, as required by the correct answer, is hard work; it was last released in 2004, and does not support php 5.3 out of the box. No Ubuntu package for it and also pecl install apd failed. So here are the procedures to install it (these are for ubuntu 10.04) (all done as root):
pecl download apd
tar xzf apd-1.0.1.tgz
cd apd-1.0.1
phpize
./configure
# Do edits (see below)
make install
See https://bugs.php.net/bug.php?id=58798 for the patch you need to do. NB. there is only one line you really have to change, so you can do it by hand, as follows: open php_apd.c in a text editor, go to line 967, and replace the CG(extended_info) = 1 line with this one:
CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
Finally, you need to add a php.ini entry to activate it. See http://php.net/manual/en/apd.installation.php
If you don't have access to APD or Runkit but are using namespaces, try this: https://stackoverflow.com/a/5337635/664108 (Answer in link refers to time() but it makes no difference)
Have a look at these:
bool rename_function ( string $original_name , string $new_name )
bool override_function ( string $function_name , string $function_args , string $function_code )
Change fsockopen to fopen to do mock, and don't change any other functions.
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
to
$fp = fopen("/path/to/your/dummy_data_file");
I blogged about my experiences which contains full working code showing how to use override_function to achieve the desired goal; both file reading and socket reading. I won't repeat that whole article here, but will just point out how you have to use the functions:
Use rename_function to give a name to the old, original function, so
we can find it later.
Use override_function to define the new behaviour
Use rename_function to give a dummy name to __overridden__
Step 1 is critical if you want to be able to restore the original behaviour afterwards.
In the Food For Thought section at the end I show an alternative approach that I think is more robust, and therefore I think it is safer for replacing file functions when using phpUnit. It creates a permanent function replacement who's default behaviour is to forward to the built-in function. It then checks parameters (the resource $handle in this case) to decide if it is being called on a stream we want different behaviour for. (I think you could call this an example of the Chain Of Responsibility design pattern.)

Remove function alias in PHP

Is there a way to remove function alias in PHP?
I can rename my function but it would be nice to use name "fetch".
Problem:
I just tested the following code and it appears to work for me, but perhaps it is because I don't have the mysqli library installed. I would test it because it might be more contextual than your IDE will have you believe. It seems to be a method for mysqli, but it might not be a global function.
<?php
function fetch(){
echo 'Hello world!';
}
fetch();
No.
(Short of recompiling the PHP binary)
This is more of a function of the IDE than the actual language... Some IDEs may give you that ability... I don't even know if recompiling the PHP binary (as Alan Storm suggested) would help since sometimes the stuff is hardcoded into the IDE / use the PHP docs online
For completeness sake: Normally, no, this can not be done. However: this can be done using a PECL extension called "runkit".
Runkit is described as "For all those things you probably shouldn't have been doing anyway", and allows you to basically tear out the innards of PHP from within PHP itself. Replacing built-in functions, undefining constants, unloading classes - suddenly everything is possible. And you should really question what you are doing if you ever feel you need it - odds are what you are doing violates some principles that are there for very good reasons, you just don't know them yet. I've never found a situation where using Runkit was a genuinely Good Idea.
Oh, in order to remove built-in functions you'll specifically need to enable this capability in your php.ini
(have fun!)

PHP 5.3 support for strange '${}' code?

I've just upgraded to PHP 5.3 and started supporting an old website for a new client. It seems to use rather odd PHP code which I've not come across before.
Whilst trying to access $_GET or $_REQUEST variables, the developer has used the following: ${"variable_name"}
I get notices generated due to undefined variables (presumably because PHP is not parsing the ${"variable_name"} style code).
Changing this to $_REQUEST['variable_name'] works as expected, but I can't go through all their code and change it as the site is massive and uses proprietry layout methods.
Does anyone know if it's possible to switch on support for these tags / codeblocks? I've taken a look in PHP.ini and there is a mention of ASP style tags and short tags but enabling these has no effect (they look totally different anyway, I just thought it was worth a shot).
I don't think there is anything new with that syntax :
$a = 10;
var_dump(${"a"});
Works just fine ;-)
You problem is probably due to the fact that, before, register_globals was enabled (by default, if PHP <= 4.something), and is now disabled -- and that is good for security !
With register_globals set to On, any variable in $_REQUEST is automatically injected as a vartiable in your application -- well, actually, this depends on the variables_order configuration option, but this one almost always includes Get, Post, and Cookie, at least.
For instance, if there is a variable like $_GET['my_var'], you will also have a $my_var variable... And this one can also be accessed with the syntax ${'my_var'}
Considering register_globals is Off by default since something like PHP 4.2, and should disappear in PHP 6 (if I remember correctly), I would advise against re-activating it... at least, if you have the time required to correct / test the code...
Curly brace syntax for variables is an embedded part of PHP, and has been around for quite awhile. The reason it exists is to resolve ambiguities with arrays and object syntaxes when using variable variables.
From the manual:
In order to use variable variables
with arrays, you have to resolve an
ambiguity problem. That is, if you
write $$a1 then the parser needs to
know if you meant to use $a1 as a
variable, or if you wanted $$a as the
variable and then the 1 index from
that variable. The syntax for
resolving this ambiguity is: ${$a1}
for the first case and ${$a}1 for
the second.
It's a very handy syntax in several situations, such as using array or object variables while outputting something using heredoc syntax.
I won't reiterate the advice by others about using register_globals, I just wanted to expound on this unusual syntax.
The ${"variable_name"} syntax is practically the same as $variable_name, except that the contents of the curly braces are evaluated first. It is supported by all recent versions of PHP, even the beta versions. What is not supported by recent versions of PHP though is the support of registering $_REQUEST (and other) variables as global variables. There's a setting for enabling it:
register_globals = on
It is NOT recommended for production use because of security issues though. It may be easier to run you source through some 'sed'-like tool and replace the usages with regular expression.
The old server probably has REGISTER_GLOBALS on. So the weird brackets aren't the problem.
REGISTER_GLOBALS puts all the variables in $_REQUEST as regular variables in the global scope, meaning you can access $_REQUEST['test'] can be accessed like $test or ${"test"}
The bracket syntax is on by default, and I don't believe you can turn it on/off.
register_globals was likely switched on. {$variable_name} syntax is always on, but register_globals turns things like $_REQUEST['variable_name'] into $variable_name.
Avoid switching it on if at all possible, though - there's a reason it's been long advised against, and it's going away entirely in PHP6.
register_globals is deprecated as of php 5.3 and will be removed as of php 6.0. What you want to do is use the Refactoring feature found in most PHP IDE's (zendo studio 6+) to rename the variable to something more appropriate, ie $_GET['variable_name'].

Categories