Take the output of gzdeflate(), for example:
$a = gzdeflate('..........');
echo $a . "\n" . strlen($a);
I get output like:
?Ӄ
5
So I've got a 5 byte string that contains characters which cannot be outputted properly, and hence cannot be copy and pasted.
Obviously, echo gzinflate('?Ӄ'); doesn't work, but echo gzinflate($a) does.
Is there any way to get the actual contents of $a onto my clipboard or output it in such a way that I could copy and paste it into gzinflate() to retrieve the original string? The only workaround I've found is something like:
$a = base64_encode(gzdeflate('..........'));
echo $a;
Which gives me:
09ODAQA=
That's friendly enough to do echo gzinflate(base64_decode('09ODAQA=')); and get .........., but I'd like to skip the base64 functions if possible.
The problem is that you're channeling binary data through a text medium. If you require the data to be printed out on your screen where you will select and copy it, there's no way to transport binary data like that.
If this is happening on the command line, you could do it programatically without displaying the actual contents. Take OS X's pbcopy and pbpaste commands:
$ php test.php | pbcopy
$ pbpaste | someotherprogram
If you do require a visible textual representation, you need to ensure that the output is ASCII-safe (or at least "Unicode safe") and not raw binary data. For that you will need to base 64 or hex encode your binary data.
I guess your browser or console just eat some special chars like break line and other.
You can put this string to any file (file_put_contents()), and open this file throw notepad++ for example. and you will see these special chars in this file.
Related
I am teaching myself programming websites with OOP in PHP (using XAMPP Version 7.3.14 for Windows), and recently I learned how to save serialized arrays containing objects (file_put_contents('path/filename.txt', serialize($array));). I did this already with normal arrays. In order to practice a bit, I wrote a little website with a form template for adding new records and a display template for printing out a list with links to individual records on screen as I encountered the following phenomenon:
In the class definition of the objects (instantiated as elements of a one-dimensional numeric array) I am working with all properties are initialized as protected and their values are got and set with getter and setter methods in the actual program code outside the class definition. When I added a new record to the array (which at that point was still read from PHP code) and saved the array for the first time the resulting .txt file is encoded in UTF-8 and the serialized string shows the "normal" syntax in latin letters such as:
a:4:{i:0;O:8:"stdClass":6:{s:13:" * property_1"; s:7:"value_1"; ...
However, after I had modified the program code in a way that the data now are read from the very .txt file (unserialize(file_get_contents('path/filename.txt', $array));) and I saved it again, the resulting file is encoded in UTF-16LE and contains Chinese characters so that it is unreadable to me! Nevertheless that file is obviously still readable by the PHP interpreter. Further testing revealed that this behaviour seems to be related to the protection status of the properties. After changing the initialization mode of the properties to public, the UTF-16LE encoded file is read but when saved again it turns back into a "normal" UTF-8 encoded file.
Finally my question: Is that known behaviour or is it a bug of my PHP interpreter? When I searched the internet I did not find anything that would fit to my observation.
PHP serialization is not a humanreadable format. Also there you can see in manual:
Note that this is a binary string which may include null bytes
https://www.php.net/manual/en/function.serialize.php
Private and protected properties brings null bytes. For example
class A{
private $b='0';
}
echo bin2hex(serialize(new A())), PHP_EOL;
echo serialize(new A());
Output
4f3a313a2241223a313a7b733a343a2200410062223b733a313a2230223b7d
O : 1 : " A " : 1 : { s : 4 : " A b " ; s : 1 : " 0 " ; }
^ ^
| | null bytes
^
| class name for private or * for protected
Null byte string is not printable, so, you text editor "decided" that you need other encoding.
Okay, this is driving me crazy. I have a small file. Here is the dropbox link https://www.dropbox.com/s/74nde57f07jj0zj/transcript.txt?dl=0.
If I try to read the content of the file using python f.read(), I can easily read it. But, if I try to run the same python program using php shell_exec(), the file read fails. This is the error I get.
Traceback (most recent call last):
File "/var/www/python_code.py", line 2, in <module>
transcript = f.read()
File "/opt/anaconda/lib/python3.4/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 107: ordinal not in range(128)
I have checked all the permission issues and there is no problem with that.
Can anyone kindly shed some light?
Here is my python code.
f = open('./transcript/transcript.txt', 'r')
transcript = f.read()
print(transcript)
Here is my PHP code.
$output = shell_exec("/opt/anaconda/bin/python /var/www/python_code.py");
Thank you!
EDIT: I think the problem is in the file content. If I replace the content with simple 'I eat rice', then I can read the content from php. But the current content cannot be read. Still don't know why.
The problem appears is that your file contains non-ASCII characters, but you're trying to read it as ASCII text.
Either it is text, but is in some encoding or other that you haven't told us (probably UTF-8, Latin-1, or cp1252, but there are countless other possibilities), or it's not text at all, but rather arbitrary binary data.
When you open a text file without specifying an encoding, Python has to guess. When you're running from inside the terminal or whatever IDE you use, presumably, it's guessing the same encoding that you used in creating the file, and you're getting lucky. But when you're running from PHP, Python doesn't have as much information, so it's just guessing ASCII, which means it fails to read the file because the file has bytes that aren't valid as ASCII.
If you want to understand how Python guesses, see the docs for open, but briefly: it calls locale.getpreferredencoding(), which, at least on non-Windows platforms, reads it from the locale settings in the environment. On a typical linux system that's not new enough to be based on systemd but not too old, the user's shell will be set up for a UTF-8 locale, but services will be set up for C locale. If all of that makes sense to you, you may see a way to work around your problem. If it all sounds like gobbledegook, just ignore it.
If the file is meant to be text, then the right solution is to just pass the encoding to the open call. For example, if the file is UTF-8, do this:
f = open('./transcript/transcript.txt', 'r', encoding='utf-8')
Then Python doesn't have to guess.
If, on the other hand, the file is arbitrary binary data, then don't open it in text mode:
f = open('./transcript/transcript.txt', 'rb')
In this case, of course, you'll get bytes instead of str every time you read from it, and print is just going to print something ugly like b'aq\x9bz' that makes no sense; you'll have to figure out what you actually want to do with the bytes instead of printing them as a bytes.
I used php shell_exec to run BLAST command (biologcal sequence alignment tool) and outputs the result in browser. However, I am not able to format the result same like it displayed when I run the same command in terminal . I tried using methods like passthru() and exec(). Both of it doesnt work! In my case, output formatting is important as a small space can make the error (a portion is give below). Can anyone tell me how to display the result in browser as exactly which in command terminal.
$cmd = "$blast -query /var/www/html/kim/blast/testing.txt -db /var/www/html/kim/blast/$db";
$result =shell_exec($cmd);
print_r ($result);
Part of my output looks like,
Query 707 TCAGACTTGAA 766
|||||||||||
Sbjct 3632 TCAGACTTGAA 3691
In order to keep formatting identical, including spaces etc., you should use the <pre> html element. An example:
echo '<pre>';
echo $result;
echo '</pre>';
Just echo the raw result. Using print_r or var_dump would lead to formatting by PHP. The above example is the most raw formatting you can achieve, given you leave result untouched.
With CSS you can then style the <pre>. But make sure to use a MONOSPACE font so that shell formatting is kept.
I am using PHP to read in a tab delimited CSV file and a pipe delimited TXT file. Unfortunately, I cannot get a string comparsion to work even though the characters (appear) to be exactly the same. I used trim to make sure to clean up hidden characters and I even tried type-casting to string.
Var dump shows they are clearly different but I am not sure how to make them the same?
// read in CSV file
$fh = fopen($mapping_date, 'r');
$mapping_data = fread($fh, filesize($mapping_date));
...
// use str_getcsv to put each line into an array
// get values out that I want to compare
$this_strategy = (string)trim($strategy_name);
$row_strategy = (string)trim($row3[_Strategy_Name]);
if($this_strategy == $row_strategy) { // do something }
var_dump($this_strategy);
Vardump: string(16) "Low Spend ($0.2)"
var_dump($row_strategy);
Vardump: string(31) "Low Spend ($0.2)"
Can't figure out for the life of me how to make this work.
Looks like you have the database encoded in UCS2 (assuming it's MySQL). http://dev.mysql.com/doc/refman/5.1/en/charset-unicode-ucs2.html
You can use possibly use iconv to convert the format - but there's an example in the comments on that page (but it doesn't use iconv - http://php.net/manual/en/function.iconv.php#49171 ). I've not tested it.
Alternatively, change the database field encoding to utf8_generic or ASCII or whatever the file is encoded as?
Edit: Found the actual PHP function you want: mb_convert_encoding - UCS2 is one of the supported encodings, so enable that in php ini and you're good to go.
I'd like to hash a file using php's hash_file(), but obfuscate it so it is not easily detected by a text string search in a text editor. Any advice? Possible?
You could use base64_encode/base64_decode to mask the name of the command being executed.
$command = "hash_file";
$encodedcommand = base64_encode($command); //aGFzaF9maWxl
Now you know that the base64 encoding of 'hash_file' is aGFzaF9maWxl.
So in your real script, just decode and execute that string:
$maskedcommand = base64_decode("aGFzaF9maWxl");
print $maskedcommand("md5",$filename);
So the string 'hash_file' isn't in the two lines of code above, but it still executes the 'hash_file' command.