Which PHP version is required for str_split? - php

I relogin to my server in dreamhost and test some scripts.And I found I couldn't use str_split. Message of Undefined function was given.I checked the version in the server and its PHP Version is 5.2.12.And I just wonder which version is required?Thanks.
Testcode:
<?php
$arr = str_split("lsdjflsdjflsdjflsdjfl");
print_r($arr);
?>
Message:
Fatal error: Call to undefined function: str_split() in /test.php on line 3
Edit #Justin Johnson
I checked the server's system directory,and I found there are two versions of PHP in Dreamhost.In user's webroot,file will be parsed by PHP5 and that's why I got php 5.2.12 by putting a phpinfo.php in the webroot.And if php files are ran in command line directly using php test.php,another php version which is 4.x worked.That's the reason I got an error.When I use
/usr/local/php5/bin/php test.php
Everything is fine.

Rather than use str_split, it's usually much easier to iterate through the characters of the string directly:
$s="abc";
$i=0;
while(isset($s[$i])) {
echo $s[$i++]." ";
}
see?

First off: The PHP documentation will always say what version is required for every function on that function's documentation page directly under the function name.
It is possible that an .htaccess file is somewhere in your path and is causing a previous version (<5) of PHP to be used. To double (or triple) check to make sure that you are running in the proper PHP version, place this code above the line where you call str_split
echo "version:", phpversion(),
"<br/>\nstr_split exists? ",
function_exists("str_split") ? "true" : "false";
However, as shown by Col. Shrapnel, it is not necessary to convert a string to an array of individual characters in order to iterate over the characters of that string. Strings can also be iterated over using traditional iteration methods, thus making the call to str_split unnecessary and wasteful (unless you need to segment the string into fixed length chunks, e.g.: str_split($s, 3))
foreach ( str_split($s) as $c ) {
// do something with character $c
}
can be replaced by
$s = "lsdjflsdjflsdjflsdjfl";
for ( $i=0; isset($s[$i]); ++$i ) {
// do something with character $s[$i]." ";
}
which is equally, if not more clear.

According to dreamhost wiki, you need to switch to php5 manually from control panel, if you created your domain before 2008 sept.
http://wiki.dreamhost.com/Installing_PHP5#Using_DreamHost.27s_PHP_5
PHP 5 was added to all plans by
DreamHost as of June 2005. As of
September 2008, support for PHP4 was
discontinued, so you can no longer
switch back to PHP 4 from PHP 5 from
the panel.
If you haven't switched to PHP 5 yet,
you can do this in the Control Panel.
But, again, you will not be able to
switch back to PHP 4 after switching
to PHP 5.
Here's how to switch from PHP 4 to PHP
5:
Log into the DreamHost Control Panel.
Click Domains, then Manage Domains.
Click the wrench icon next to the domain you want to activate PHP 5
on (under the Web Hosting column).
Select PHP 5.x.x from the dropdown menu.
Click Change fully hosted settings now! at the bottom of the
section.
Repeat steps 3-5 for each additional domain you want to
activate.
you could also check your php version with
<?php
phpinfo();
?>

The version required is PHP 5 or later. So theoretically your program should work.

If you can't get str_split to work, just use a string as an array:
$stuff = "abcdefghijkl";
echo $stuff[3];
will produce
d
This method is fastest, anyway. I don't know if it suits your needs, but if it does, I hope it helps!

Could be anything in your code. How do we know its not a 10 line script or 2000 line script?

You can use preg_split() to split an array into single characters, but it will return an extra empty string at the begining and the end.
$a = preg_split("//","abcdefg");
echo json_encode($a);
prints:
["","a","b","c","d","e","f","g",""]

Related

Why PHP COM objects are not returning correct results?

I'm trying to access Windows SAPI5 or Text to speech (TTS) using PHP. The standard approach is to create a COM object for "SAPI.SpVoice", then get the installed voices.
Sample PHP code:
<?php
$obj = new COM('SAPI.SpVoice');
$voices = $obj->GetVoices;
$count = $voices->Count;
print $count; #prints "1"
Unfortunately the output returned from PHP's COM object is incorrect because I have 5 voices installed on my system, but PHP only returns 1.
So, just to check if this a PHP specific issue, I wrote the same code in Perl 5.8 (strawberry).
Sample Perl code:
#!/usr/bin/perl
use Win32::OLE;
my $obj = Win32::OLE->new('SAPI.SpVoice');
my $voices = $obj->GetVoices;
my $count = $voices->Count;
print $count; #print "5" which is correct.
So the perl code correctly returns that I have 5 TTS voices on my system, but PHP returns only 1?
Is this a bug or am I doing something wrong? What could be the possible cause of this?
P.S. I've tried this on two different computers and results are the same.
I figured this after some trial error. It looks like if I use the 32-bit version of PHP then I get the correct results (5 voices). But since I had installed the 64-bit version by default I only get 1 voice.
I think the TTS voices are mostly 32 bit (like those installed on my system) and so when running with a 64-bit php.exe it only returns 64-bit voices. With 32 php.exe it returns all voices.
Posting this as answer in case someone faces a similar issue in future.

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.

Options for PHP CLI on windows

I'm working with the PHP CLI on windows at the moment to write some small desktop command-line apps.
I wanted to know if and how it may be possible to:
Clear the screen (cls would be the normal command but exec() won't work with it)
Change the color, change the color of parts of the output (seen this in programs before)
Make the command line horizontally bigger - things quickly get unreadable
Is any of the above possible from inside a PHP script?
On Windows, in the standard CLI prompt, you cannot output in colour (as in the answer by Spudley).
You can change the size of the window as a user by right-clicking the command window's title bar and selecting Properties, then ammending values in the Layout tab. I do not think it is possible to ammend the width of the CLI within PHP.
You can check the width of the CLI window on Windows using the function I wrote here
See the PHP manual page for working with the commandline
To directly answer each of your bullet points:
There is a comment on that page which gives a function that can clear the screen. I'll quote it here for you:
<?php
function clearscreen($out = TRUE) {
$clearscreen = chr(27)."[H".chr(27)."[2J";
if ($out) print $clearscreen;
else return $clearscreen;
}
?>
There's also another comment which explains how to change the colours. Again, I'll quote it:
<?php
echo "\033[31m".$myvar; // red foreground
echo "\033[41m".$myvar; // red background
?>
and to reset:
<?php
echo "\033[0m";
?>
You should read through the rest of that page for a whole load more suggestions on how to manipulate the CLI.
The only part of your question that leave unanswered is the third bullet point. Sadly, I don't believe you'll be able to do this, and I don't think it's possible to horizontally resize the Windows command line window.
Hope that helps.
I created a small backup script with PHP, and from what I can remember, you can print backspace characters to remove content. Not really ideal though.
Just google'd it: http://www.php.net/manual/en/features.commandline.php#77142
As far as the third question goes, I suggest you witch the default command line to Console 2. It is a great replacement that not only lets you use any width you like (as long as it fits your screen), but also supports command history, tabs, and some UI sugar.
The provided code will not work under Windows because PHP under windows does something to the command window. I am not sure what PHP does but I wrote a simple Freebasic program with only two lines:
cls
end
I then compiled it and ran it under a regular command line window. It cleared the screen without any kind of a problem. I then did the following in PHP:
<?php
echo "This is a test\n";
system( "cls.exe" );
exec( "cls.exe" );
passthru( "cls.exe" );
?>
When I ran the program it did nothing more than just the "This is a test" line. Thus, there is some kind of suppression going on with PHP that looks for and stops any kind of escape sequence from occurring. Until this is fixed in PHP - you will never be able to do a cls, nor use curses, ncurses, or any other library. What has to be done is to integrate something like FreeBasic's windowing methods as some kind of a class (or maybe just a C set of routines) that will open a new window via THAT language's methodologies and use them to do the text window. Then all of the escape sequences will work. Until then - they won't.
What I find weird about this is that PHP was originally written in Perl and Perl will do ncurses on Windows without any problems. Perl will also allow all escape sequences to work. So there is just something being done on the Windows compile that is causing this problem.

Categories