Increasing performance of exec() statement - php

I have an issue, that is not necessarily in the scope of most questions asked here.
I have an application I am developing that checks a domain for certain A records and also tests ports on the resolving server to check if they are open and listening.
I have added functionality on my local copy of the site, but it is too slow for me to publish, come to think of it, so is the current published site.
You can see the app on the link: http://www.domainion.co.za
Enter a domain name (without www) and it will check for certain records.
This is a symfony app, I am getting these records by running multiple exec() statements with digs for specific information. The reason I like using exec, is because if there are multiple records returned, like the below command, it lets you assign each result to an index of an array.
dig -x 154.0.174.35 +short #8.8.8.8
motairgdiool.hosted.co.za. (index 0)
kent.aserv.co.za. (index 1)
Now, this is taking way too long (on average 8 seconds to load). My issue with this, is if you had to take all these commands in this app and run it in a shell script, they take under a second to run, I suspect the reason mine takes so long, is that PHP is opening and closing a virtual shell for each of these commands.
In an attempt to run these queries quicker, I have tried the below:
shell_exec() - This takes about the same time, and returns all results as a string, I can't use that.
proc_open - takes longer, also returns a long string.
symfony process() component - takes waaay longer and also returns all results as one string
dns_check_record() - you can't check for specific subdomain records
TLDR : Is there any way I can get records that i want (n.domain.tld) and still have the application run fast?
Thanks

$ php -r 'var_dump(dns_get_record("35.174.0.154.in-addr.arpa"));'
Returns the following in under a one fifth of a second, including invoking the PHP interpreter:
array(2) {
[0]=>
array(5) {
["host"]=>
string(25) "35.174.0.154.in-addr.arpa"
["class"]=>
string(2) "IN"
["ttl"]=>
int(7192)
["type"]=>
string(3) "PTR"
["target"]=>
string(16) "kent.aserv.co.za"
}
[1]=>
array(5) {
["host"]=>
string(25) "35.174.0.154.in-addr.arpa"
["class"]=>
string(2) "IN"
["ttl"]=>
int(7192)
["type"]=>
string(3) "PTR"
["target"]=>
string(25) "motairgdiool.hosted.co.za"
}
}

Use local DNS. It would be faster than a query to #8.8.8.8
dig -x 154.0.174.35 +short

Related

php/bash script adds a parameter to command line

<?php var_dump($argv); ?>
ok - run it directly - get what's expected.
$ php /tmp/check-arg.php -s test yellow bus
array(5) {
[0]=>
string(18) "/tmp/check-arg.php"
[1]=>
string(2) "-s"
[2]=>
string(4) "test"
[3]=>
string(6) "yellow"
[4]=>
string(3) "bus"
}
ok - so I want to run this script as if it were a command (it's a php script that replaces an existing command), so I created this script
$ vi /tmp/testingcommand
php /tmp/check-arg.php $1 $2 $3 $4 $5 $6 $7 $8 $9 $10
(edit - change the $10 to {10} is solution - or use "$#" instead of $1 $2...)
so I should be able to just
$ /tmp/testingcommand -s test yellow bus
array(6) {
[0]=>
string(18) "/tmp/check-arg.php"
[1]=>
string(2) "-s"
[2]=>
string(4) "test"
[3]=>
string(6) "yellow"
[4]=>
string(3) "bus"
[5]=>
string(3) "-s0"
}
OK - so where did that "-s0" come from? I've done some fiddling and it's what is in $argv[1] (-s) and a "0" (so in this case -s0)
Any ideas? happened on our RHEL7 as well as a Fedora 30 setup
since the script can be run either directly (php program.php) or via a script I can't just ignore the last index of argv[]
I guess I could check argv[0] for '...php' and keep all indexs and if no ...php then ignore last index
-s0 came from $10. That's $1 followed by 0.
Use ${10} to access parameter 10. You need curly braces whenever the parameter number is more than one digit.
Note that your code won't work properly if any of the arguments have spaces, because you're not quoting the variables. The variable value will undergo word splitting and wildcard expansion.
But if you quote all the variables, you'll get explicit '' values for the arguments that weren't supplied, which is probably not desired, either.
The correct way to reference all the arguments is with "$#".
php /tmp/check-arg.php "$#"

Different server, different datatype with the exact same code

I'm running a code getting data from a DB server, everything is working fine locally. But when I push it online, it's not working anymore.
I think I know where the problem comes from. Here is the data I get locally:
object(stdClass)#451 (14) {
["matter_created_actionstep_c"]=>
string(1) "1"
["trust_receipt_sent_c"]=>
string(1) "1"
["scope_complete_c"]=>
string(1) "0"
["transferred_trust_to_current_c"]=>
string(1) "0"
}
And when I push it on my server, here is the result I get:
object(stdClass)#451 (14) {
["matter_created_actionstep_c"]=>
int(1)
["trust_receipt_sent_c"]=>
int(1)
["scope_complete_c"]=>
int(0)
["transferred_trust_to_current_c"]=>
int(0)
}
Are you aware of any apache configuration that would lead to this typeset change?
The only project file that is different, is the conf file:
locally:
DB_HOST=1.1.1.1
on the server:
DB_HOST=localhost
Thanks in advance.
This can result from a lot of issues. Maybe a different PHP version, maybe the data comes from a database and the version of the database driver is different, …
I would say the application is to blame. PHP is untyped, meaning in most cases nobody cares for the actual type of a variable. In your case barely anybody cares if the value is 2 or "2" as long as it behaves the same (e.g. 2==2 equals 2=="2"). If the application requires certain types in some variables, it should assure the variables contain these types! This is not the case here.
Check the application and the part of the code which writes the value into the object. This part of code should cast the value to the desired type before putting it into the variable.
Nevertheless (or if the object comes from somewhere else) it may make sense to make the code more forgiving concerning types, i.e. do not rely on a special type as long as it is not necessary. In my experience there are only few cases when type of variables really matter.

"Computed" key from Sql server scalar functions

I have a project that uses MSSQL over pdo_dblib and freetds. MS scalar functions always returned their data in this format:
array(1) { [0]=> array(1) { ["computed"]=> string(3) "922" } }.
But now, on one of the servers the format suddenly is:
array(1) { [0]=> array(1) { [""]=> string(3) "922" } }.
So the key in the array became empty instead of "computed".
I know that I can change that key in my select statements by adding "as" clause. Still, the question is, what controls the default key?
Both servers use the same database.
As far as I know, this "computed" key is something that's added by pdo_dblib.
PHP version is different between servers, the one with computed has old 5.3, while the one with empty key has 5.5. But I think that this server had 5.5 for quite some time, while the computed key disappeared just yesterday. Not 100% sure though...
In the end I found out that this happens because there was a change in this commit to pdo_dblib. The motivation for this change was that it was clogging up memory.
It should be noted that the version that you get from pecl is weird. It has "computed" in dblib_stmt.c source, but still does not use it.
The version that works, is the one bundled with php sources. I was able to take sources from php-5.3.29\ext\pdo_dblib\ and build them against 5.6.4.

Override $argv for getopt

example.php:
$args = __FILE__.' -vvv';
$argv = explode(' ', $args);
$argc = count($argv);
$GLOBALS['argv'] = $_SERVER['argv'] = $argv;
$GLOBALS['argc'] = $_SERVER['argc'] = $argc;
var_export(getopt('v'));
$ example.php -v
> array('v' => false);
Eventually getopt does not look up to $GLOBALS to get argv. So it there any way I can override argv array?
TL;DR
No, there is no native way to do this. Depending of your goals there may be other ways to resolve the issue, but overriding is not one of them.
Operating on super-globals
Structure
To realize why it is so, you should know, that super-globals are not just "variables" to which you are referring. That means, if you are using $argv to de-reference arguments list, it does not mean that you'll access some data which is stored in "variable" $argv. Instead, you'll access to data container by "link", called $argv. However, there are different ways to access this data - $_SERVER['argv'] or $GLOBALS array at least. To illustrate, I'll go with the code:
var_dump($argv, $_SERVER['argv']);
unset($argv);
var_dump($argv, $_SERVER['argv']);
This will result in something like:
array(2) {
[0]=>
string(11) "example.php"
[1]=>
string(4) "-vvv"
}//<--------------------- derived from $argv
array(2) {
[0]=>
string(11) "example.php"
[1]=>
string(4) "-vvv"
}//<--------------------- derived from $_SERVER['argv']
NULL//<------------------ we've unset $argv, so unset a reference
array(2) {
[0]=>
string(11) "example.php"
[1]=>
string(4) "-vvv"
}//<--------------------- but data is still there and available via another reference
Internally
As you can see, the reference can be destroyed, but actual data will remain untouched. That will be stored in symbols table. Many PHP functions are accessing this structure to retrieve data, and getopt() is not an exception. So the conclusion is - yes, you can modify the reference (or even destroy it), but actual data will be still in super-globals.
getopt()
Now, about this function. Just take a look at its implementation:
/* Get argv from the global symbol table. We calculate argc ourselves
* in order to be on the safe side, even though it is also available
* from the symbol table. */
if (PG(http_globals)[TRACK_VARS_SERVER] &&
(zend_hash_find(HASH_OF(PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv"), (void **) &args) != FAILURE ||
zend_hash_find(&EG(symbol_table), "argv", sizeof("argv"), (void **) &args) != FAILURE) && Z_TYPE_PP(args) == IS_ARRAY
)
{
//...omitted
}
It's clearly stated, that it will try to search "argv" in symbol_table (if you want - here's a link to - how it will be done exactly). And that means - it will access actual data, thus, overriding it externally will have no effect.
As a result - getopt() will work with data which were gathered at script startup, and that data will contain actual parameters, no matter if you'll override them inside your script.

Why does assigning to a local variable overwrite part of $_SESSION? [duplicate]

I've encountered a very odd issue in regards to session variables and local variables in php.
I'm trying to figure out if I am not understanding something about sessions in php or if this is an issue with the php version my host is using.
Here is a very simple code to demonstrate the weird issue:
session_start();
var_dump($kenny);
var_dump($_SESSION['kenny']);
$_SESSION['kenny']='def';
var_dump($kenny);
var_dump($_SESSION['kenny']);
$kenny = 'abc';
var_dump($kenny);
var_dump($_SESSION['kenny']);
The first time I run the code, I get the following results (as one would expect):
NULL NULL NULL string(3) "def" string(3) "abc" string(3) "def"
I run it a second time (without closing my browser, of course), I get this now!
string(3) "def" string(3) "def" string(3) "def" string(3) "def" string(3) "abc" string(3) "abc"
I run it a 3rd, 4th, 5th time and so on, I get this!!!
string(3) "abc" string(3) "abc" string(3) "def" string(3) "def" string(3) "abc" string(3) "abc"
It looks to me like the session variable 'kenny' and local variable $kenny become aliases to one and the other after running the script more than once. hmm... I really don't think this is how session variables and local variables work in php. Please correct me if I'm missing something here.
My web host is running php 5.2.2. When I try this exact same code on other hosts running php 5.2.1, 5.2.14 and 5.3.1, they always give me what I expect:
1st time:
NULL NULL NULL string(3) "def" string(3) "abc" string(3) "def"
thereafter:
NULL string(3) "def" NULL string(3) "def" string(3) "abc" string(3) "def"
I checked the change log on php.net and didn't find anything that I can relate to that may address this issue. But like I mentioned, an earlier build (5.2.1) works ok, so that's very puzzling to me.
If anyone runs any other version of php 5.2.x, please give it a try and let me know if you see the same issue. Or if anyone has any insight into the issue, I'd really appreciate any feedback.
Thanks a million!
This is probably because the register_globals directive is on. It doesn't say it on that page that $_SESSION variables are included, but it says here:
If register_globals is enabled, then
the global variables and the
$_SESSION entries will automatically
reference the same values which were
registered in the prior session
instance. However, if the variable is
registered by $_SESSION then the
global variable is available since the
next request.

Categories