Command Prompt Width Within PHP - php

I'm running PHP on a Windows Server and I have a script that uses PowerShell to perform some WMI queries. I'm taking the results of the query and exploding it by line break so that each property of the WMI class is its own line (and later will be used for other stuff).
The problem I'm having is that by default, the command prompt window width is limited to 80 characters so when the PHP script obtains the results of the WMI query, certain lines that exceed 80 characters are broken up into numerous lines and I'd really like each line to only be one line regardless of how long the string is.
I've tried logging into the server and changing the default width of the command prompt as well as both 32- and 64-bit PowerShell windows. When I run the commands directly in those applications, I can see it's no longer breaking on 80 characters. However, my PHP script still does.
Here's a snippet of my code:
exec("powershell.exe -Command \" & { Get-WmiObject -Query 'Select * From Win32OperatingSystem' | Format-List *} \" ", $Output, $ReturnValue);
foreach ($Output as $PSOutput) {
$ExplodePSOutput = explode("\r\n", $PSOutput);
foreach ($ExplodePSOutput as $WMIProperty) {
echo $WMIProperty."<br>";
}
}
Here's an example of what the output is like:
Status : OK
Name : Microsoft Windows 10 Enterprise|C:\
WINDOWS|\Device\Harddisk0\Partition
2
FreePhysicalMemory : 9224968
But I'm wanting it to look like this:
Status : OK
Name : Microsoft Windows 10 Enterprise|C:\WINDOWS|\Device\Harddisk0\Partition2
FreePhysicalMemory : 9224968
Update:
My ultimate goal was to extract each property name from the selected WMI class. Since each property named was followed with " : ", I was able to work around this problem by searching each exploded string for this pattern and returning the value to the left of that. If that pattern doesn't exist, it's presumably a line that was broken because it went over the 80 character limit.
$PatternPosition = strpos($WMIPropertyResult, " : ");
$WMIPropertyName = substr($WMIPropertyResult, 0, $PatternPosition);
PowerShell formats the output to align all of the property values but it formats it based on the longest property name and property names will obviously change based on what WMI class is being queried. So it makes more sense to search for the " : " pattern instead of hardcoding a value in the substr() function.
I'll leave this post around in case anyone has a suggestion on the original question but for my use case, I believe I have a sufficient workaround.

Related

How to call a php file with arguments from VBA for Mac? Equivalent of VBA.createObject("wscript.shell") on Mac?

Still in need of help :)
I'm trying to adapt the following chunk of code to VBA for Mac (as the final implementation has to be on Mac):
Dim ws as Object
Dim result as String
Set ws = VBA.CreateObject("wscript.shell")
cd = "php " & dirPHP & "\verificar.php " & FileName
result = ws.Run(cd)
Set ws = Nothing
It runs perfectly on Windows, but when trying to adapt it for Mac I'm encountering many problems.
What I am basically doing on the previous chunk is calling a PHP file that takes the first argument (in this case, FileName) and calls the verify function, returning some values.
The thing is that there are some posts explaining how to do this, but I have seen no examples on how to do it for PHP, and especially for PHP passing an input argument.
This is what I've tried so far:
result = AppleScriptTask("PHPCommand.applescript", "PHPCommandHandler", FileName)
e = "php " & dirPHP & "/verificar.php " & FileName cd = "do shell script """ & e & """" result = MacScript(cd)
(On the Mac Terminal I am able to run the PHP file fine, with the resulting "e" string).
And some other fruitless things, like the shell() function, or some other user-defined functions (I saw someone defined a "system()" function). I also tried many ways of putting the double and simple quotes, and simplified the path to the PHP file (dirPHP) and the path + filename of the argument (FileName) by removing all blank spaces and thus the need of using additional quotes.
Please help me! I'd be really grateful, as yesterday I spent the whole day on this and I can't keep wasting time on something that is so simple on Windows... But I have to do it on Mac.
Thanks so much!!!
Use the VBA Shell function.
Shell
Runs an executable program and returns a Variant (Double) representing
the program's task ID if successful; otherwise, it returns zero.
Syntax
Shell(pathname, [ windowstyle ])

bash script not executing mysql command with values passed as variables

I am modifying a set of bash scripts that process video files and reports the processing steps to a mysql database (here is the original code in question).
The function that does the database reporting is called from the main processing script and looks like this in the original:
_report_to_db(){
if [ "${REPORT_TO_DB}" = "Y" ] ; then
echo "INSERT IGNORE INTO tableA (objectIdentifierValue,object_LastTouched) VALUES ('${MEDIA_ID}',NOW()) ON DUPLICATE KEY UPDATE object_LastTouched = NOW()" | mysql --login-path="${LOGIN_PROFILE}" "${DB_NAME}" 2> /dev/null
_db_error_check
fi
}
Since the scripts are meant to be run directly from the command line, when you run them that way it works fine. But I'm running them via php from a web interface and there's some shenanigans going on with the quoting/escaping of whitespace and/or variables.
For instance, the script breaks on the whitespace after ...| mysql and it thinks I'm trying to run mysql as root without a password and totally ignores the --login-path and the other stuff I'm piping to it.
When I call mysql from a variable like so:
_report_to_db(){
if [ "${REPORT_TO_DB}" = "Y" ] ; then
SQL_ARRAY=(INSERT IGNORE INTO tableA (columnA,lastTouched) VALUES ("${SOME_PASSED_VALUE}",NOW()) ON DUPLICATE KEY UPDATE object_LastTouched = NOW();)
MYSQL_COMMAND_ARRAY=(mysql --login-path="${LOGIN_PROFILE}" -e "${SQL_ARRAY[#]}" "${DB_NAME}")
echo "$(${MYSQL_COMMAND_ARRAY[#]})"
_db_error_check
fi
}
... I am able to log into mysql correctly but the SQL query is ignored (when it echos the result you get the standard MySQL --help output.
So far I have tried all kinds of variations on quoting, escaping, referencing the query as a separate string variable, as an array (as you see here).
What is also not helpful is that the original _db_error_check() function only checks the value of the pipe exit status. So if the pipe is ok, but there's a problem further down the path, it fails silently.
_db_error_check(){
if [ "$?" != "0" ] ; then
# reports an error if the pipe exit value ≠ 0
else
# everything is ok! even if there was a mysql error
fi
}
This is not a file or database permissions issue (already triple checked that). Are there quotes or some other stupid thing that I am missing?? Thanks! Oh, I am running OSX El Capitan.
UPDATE
Lol, I was going to post the PHP that calls the script and then I remembered that the PHP is actually calling a Pyhton script that does some other processing too, and that is what calls the bash script. Here it all is:
PHP
$command = escapeshellcmd("/usr/local/bin/python3 /Users/user/path/to/ingest.py " . $user . " 2>&1");
while (# ob_end_flush());
$proc = popen($command, 'r');
echo '<pre>';
while (!feof($proc))
{
echo fread($proc, 4096);
# flush();
}
echo '</pre>';
PYTHON
for item in os.listdir(ingestDir):
if not item.startswith("."):
filePath = os.path.abspath(ingestDir+"/"+item)
fileNameForMediaID = os.path.splitext(item)[0]
try:
ingest = subprocess.Popen(['/usr/local/bin/ingestfile','-e','-u',user,'-I',filePath,'-m',fileNameForMediaID])
ingest.wait()
os.remove(filePath)
except IOError as err:
print("OS error: {0}".format(err))
UPDATE 2
I think this might actually be a weird quirk of my installation (go figure). Using mysql --login-path=myDbUser [etc...] from a shell on my host machine I keep getting the error ERROR 1045 (28000): Access denied for user 'ADMIN'#'localhost' (using password: NO) where the client user is ADMIN and I am trying to login as myDbUser.
I actually uninstalled and reinstalled mysql (via Homebrew) and still have the same results. Using a different machine (running Sierra, but the same mysql version) I can run the above shell command successfully and log into mysql as the target user.
Also on the host machine, I can sudo -u _www zsh and run the command as the Apache user (which is the user running the whole show) without a problem. SO WHY IS IT NOT RUNNING CORRECTLY EITHER IN THE SCRIPT OR EVEN RUN FROM SHELL AS MY MAIN CLIENT USER???
Any ideas? $PATH is identical in all cases mentioned above. Same ~/.mylogin.cnf setups. Is there anything else stupid obvious I missed?
You need to use indirect expansion here:
echo "$(${MYSQL_COMMAND_ARRAY[#]})"
the man says:
If the first character of parameter is an exclamation point (!), and
parameter is not a nameref, it introduces a level of variable
indirection. Bash uses the value of the variable formed from the rest
of parameter as the name of the variable; this variable is then
expanded and that value is used in the rest of the substitution,
rather than the value of parameter itself. This is known as indirect
expansion. If parameter is a nameref, this expands to the name of the
variable referenced by parameter instead of performing the complete
indirect expansion. The exceptions to this are the expansions of
${!prefix*} and ${!name[#]} described below. The exclamation point
must immediately follow the left brace in order to introduce
indirection.
${!name[#]}
${!name[*]}
If name is an array variable, expands to the list of array indices
(keys) assigned in name. If name is not an array, expands to 0 if name
is set and null otherwise. When ‘#’ is used and the expansion appears
within double quotes, each key expands to a separate word.
PS: If I may put forward a piece of my personal opinion, having a chain of php -> python -> bash is the worst coding style one can ever met, you may want to rewrite it into single langue so it will be easier to track down further issues at least.

Getting different output for same PHP code

(Can't paste the exact question as the contest is over and I am unable to access the question. Sorry.)
Hello, recently I took part in a programming contest (PHP). I tested the code on my PC and got the desired output but when I checked my code on the contest website and ideone, I got wrong output. This is the 2nd time the same thing has happened. Same PHP code but different output.
It is taking input from command line. The purpose is to bring substrings that contact the characters 'A','B','C','a','b','c'.
For example: Consider the string 'AaBbCc' as CLI input.
Substrings: A,a,B,b,C,c,Aa,AaB,AaBb,AaBbC,AaBbCc,aB,aBb,aBbC,aBbCc,Bb,BbC,BbCc,bC,bCc,Cc.
Total substrings: 21 which is the correct output.
My machine:
Windows 7 64 Bit
PHP 5.3.13 (Wamp Server)
Following is the code:
<?php
$stdin = fopen('php://stdin', 'r');
while(true) {
$t = fread($stdin,3);
$t = trim($t);
$t = (int)$t;
while($t--) {
$sLen=0;
$subStringsNum=0;
$searchString="";
$searchString = fread($stdin,20);
$sLen=strlen($searchString);
$sLen=strlen(trim($searchString));
for($i=0;$i<$sLen;$i++) {
for($j=$i;$j<$sLen;$j++) {
if(preg_match("/^[A-C]+$/i",substr($searchString,$i,$sLen-$j))) {$subStringsNum++;}
}
}
echo $subStringsNum."\n";
}
die;
}
?>
Input:
2
AaBbCc
XxYyZz
Correct Output (My PC):
21
0
Ideone/Contest Website Output:
20
0
You have to keep in mind that your code is also processing the newline symbols.
On Windows systems, newline is composed by two characters, which escaped representation is \r\n.
On UNIX systems including Linux, only \n is used, and on MAC they use \r instead.
Since you are relying on the standard output, it will be susceptible to those architecture differences, and even if it was a file you are enforcing the architecture standard by using the flag "r" when creating the file handle instead of "rb", explicitly declaring you don't want to read the file in binary safe mode.
You can see in in this Ideone.com version of your code how the PHP script there will give the expected output when you enforce the newline symbols used by your home system, while in this other version using UNIX newlines it gives the "wrong" output.
I suppose you should be using fgets() to read each string separetely instead of fread() and then trim() them to remove those characters before processing.
I tried to analyse this code and that's what I know:
It seems there are no problems with input strings. If there were any it would be impossible to return result 20
I don't see any problem with loops, I usually use pre-incrementation but it shouldn't affect result at all
There are only 2 possibilities for me that cause unexpected result:
One of the loops iteration isn't executed - it could be only the last one inner loop (when $i == 5 and then $j == 5 because this loop is run just once) so it will match difference between 21 and 20.
preg_match won't match this string in one of occurrences (there are 21 checks of preg_match and one of them - possible the last one doesn't match).
If I had to choose I would go for the 1st possible cause. If I were you I would contact concepts author and ask them about version and possibility to test other codes. In this case the most important is how many times preg_match() is launched at all - 20 or 21 (using simple echo or extra counter would tell us that) and what are the strings that preg_match() checks. Only this way you can find out why this code doesn't work in my opinion.
It would be nice if you could put here any info when you find out something more.
PS. Of course I also get result 21 so it's hard to say what could be wrong

Is there a limit on the length of command passed to exec in PHP?

Currently I need to merge that 50+ PDF files into 1 PDF. I am using PDFTK. Using the guide from: http://www.johnboy.com/blog/merge-multiple-pdf-files-with-php
But it is not working. I have verified the following:
I have tried the command to merge 2 pdfs from my PHP and it is working.
I have echo the final command and copied that command and paste into command prompt and run manually and all the 50 PDFs are successfully merged.
Thus exec in my PHP and the command to merge 50 PDFs are both correct but it is not working when done together in PHP. I have also stated set_time_limit(0) to prevent any timeout but still not working.
Any idea what's wrong?
You can try to find out yourself:
print exec(str_repeat(' ', 5000) . 'whoami');
I think it's 8192, at least on my system, because it fails with strings larger than 10K, but it still works with strings shorter than 7K
I am not sure if there is a length restriction on how long a single command can be but I am pretty sure you can split it accross multiple lines with "\" just to check if thats the problem. Again I dont think it is... Is there any error output when you try to run the full command with PHP and exec, also try system() instead of exec().
PDFTK versions prior to 1.45 are limited to merge 26 files cuz use "handles"
/* Collate scanned pages sample */
pdftk A=even.pdf B=odd.pdf shuffle A B output collated.pdf
as you can see "A" and "B" are "handles", but should be a single upper-case letter, so only A-Z can be used, if u reach that limit, maybe you script outputs an error like
Error: Handle can only be a single, upper-case letter
but in 1.45 this limitation was removed, changelog extract
You can now use multi-character input handles. Prior versions were
limited to a single character, imposing an arbitrary limitation on
the number of input PDFs when using handles. Handles still must be all
upper-case ASCII.
maybe you only need update your lib ;)

PHP preg_split Apache & Powershell equivalent

What Im Building:
The script archives a working directory using GIT-POSH and sends it to a Linux Apache Server using a Windows Powershell SSH Module.
For convenience, the script also needs to do reporting on existing files on the local machine as well as the Apache server.
The Problem:
This is where I need string manipulation to separate each block in the naming convention.
I was going to use underscores block_block until I realized some of the blocks contain underscores them already.
This is when I decided to encapsulate each block with brackets [block][block]
In PHP I would use preg_split to pull out each piece into an associative array.
[product][branch_name][date][time][commit_hash]
Expected Usage:
--> Get-Product $string
--> product123
--> Get-Branch $string
--> branch123
Questions I have:
How do I preg_split this string the same way using powershell and apache?
A better naming convention that supports the same operation?
PHP's preg_split can be mimicked with System.RegularExpressions.Split(). There are some caveats, namely Split() will return empty strings for tokens it replaced, so some filtering is needed. Like so,
$data = "[product][branch_name][date][time][commit_hash]"
$arr = [Regex]::Split($data, "[\[\]]") | ? { $_.length -gt 0 }
$arr
Output:
product
branch_name
date
time
commit_hash
Without the filtering clause ? { $_.length -gt 0 } - which will exclude string objects that have length of zero - the output would be slightly different:
product
branch_name
date
time
commit_hash
This behaivour is documented in MSDN.

Categories