Failed to open stream: VariableStream::stream_open - php

I'm currently implementing a function that generated an image I can use to print it on a PDF file with FPDI. During the creation of the image from the memory, I'm getting this error:
PHP Warning: getimagesize(var://imgd41d8cd98f00b204e9800998ecf8427e):
failed to open stream: "VariableStream::stream_open" call
failed in /Applications/MAMP/htdocs/fpdi/src/fpdi_extended.php on line
77
I don't get it anymore. This is my code:
<?php
require_once 'autoload.php';
use setasign\Fpdi\Fpdi;
class VariableStream {
private $varname;
private $position;
public function streams_open( $path, $mode, $options, &$opened_path ): bool {
$url = parse_url( $path );
$this->varname = $url['host'];
if ( ! isset( $GLOBALS[ $this->varname ] ) ) {
header( 'HTTP/1.1 500 Internal Server Error' );
header( 'Content-Type: application/json; charset=UTF-8' );
die( json_encode( array(
'message' => 'Global variable ' . $this->varname . ' does not exist',
'code' => 1337
) ) );
}
$this->position = 0;
return true;
}
public function stream_read( $count ) {
$ret = substr( $GLOBALS[ $this->varname ], $this->position, $count );
$this->position += strlen( $ret );
return $ret;
}
public function stream_eof(): bool {
return $this->position >= strlen( $GLOBALS[ $this->varname ] );
}
public function stream_tell() {
return $this->position;
}
public function stream_seek( $offset, $whence ): bool {
if ( $whence === SEEK_SET ) {
$this->position = $offset;
return true;
}
return false;
}
public function stream_stat(): array {
return array();
}
}
class Fpdi_Extended extends Fpdi {
public function __construct( $orientation = 'P', $unit = 'mm', $format = 'A4' ) {
parent::__construct( $orientation, $unit, $format );
// Register var stream protocol
stream_wrapper_register( 'var', 'VariableStream' );
}
public function MemImage( $data, $x = null, $y = null, $w = 0, $h = 0, $link = '' ): void {
// Display the image contained in $data
$v = 'img' . md5( $data );
$GLOBALS[ $v ] = $data;
$a = getimagesize( 'var://' . $v );
if ( ! $a ) {
header( 'HTTP/1.1 500 Internal Server Error' );
header( 'Content-Type: application/json; charset=UTF-8' );
die( json_encode( array( 'message' => 'ERROR: Invalid signature data.', 'code' => 1337 ) ) );
}
$type = substr( strstr( $a['mime'], '/' ), 1 );
$this->Image( 'var://' . $v, $x, $y, $w, $h, $type, $link );
unset( $GLOBALS[ $v ] );
}
public function GDImage( $im, $x = null, $y = null, $w = 0, $h = 0, $link = '' ): void {
// Display the GD image associated with $im
ob_start();
imagecreatefromstring( base64_decode( preg_replace( '#^data:image/\w+;base64,#i', '', $im ) ) );
$data = ob_get_clean();
$this->MemImage( $data, $x, $y, $w, $h, $link );
}
}
I'm calling the code this way:
require_once 'fpdf/fpdf.php';
require_once 'fpdi/src/fpdi_extended.php';
$pdf = new Fpdi_Extended();
$page_counter = $pdf->setSourceFile( 'template.pdf' );
$tplIdx = $pdf->importPage( 5 );
$pdf->AddPage();
$pdf->useTemplate( $tplIdx, 10, 10, 100 );
$pdf->GDImage( $signature );
imagedestroy( $signature );
$pdf->Output();
After fixing the typo issue streams_open -> stream_open, I'm hanging here:
PHP Notice: getimagesize(): Read error! in
/Applications/MAMP/htdocs/fpdi/src/fpdi_extended.php
An example value for $signature is: data:image/png;base64,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

Not able to install the FPDI package at the moment but I think you need to convert the image to a PNG before reading it from memory. Try editing your GDImage function like so:
public function GDImage( $im, $x = null, $y = null, $w = 0, $h = 0, $link = '' ): void {
ob_start();
$resource = imagecreatefromstring( base64_decode( preg_replace( '#^data:image/\w+;base64,#i', '', $im ) ) );
imagepng($resource);
$data = ob_get_clean();
$this->MemImage( $data, $x, $y, $w, $h, $link );
}

With the help of waterloomatt I've found my solution. I've changed the function below:
public function GDImage( $im, $x = null, $y = null, $w = 0, $h = 0, $link = '' ): void {
// Display the GD image associated with $im
$resource = imagecreatefromstring( base64_decode( preg_replace( '#^data:image/\w+;base64,#i', '', $im ) ) );
imagesavealpha( $resource, true );
ob_start();
imagepng( $resource );
$data = ob_get_clean();
imagedestroy( $resource );
$this->MemImage( $data, $x, $y, $w, $h, $link );
}
First, I was confused because the save base64 image on my PDF was completely black. So I've informed me about the used methods. So I came across this function here which saves some color informations in the resource:
imagesavealpha( $resource, true );
Now it's working great. Thanks to waterloomatt for the time!

Related

script that denies access to an ip after they have filled a form on my site

I have an existing php script written which checks if an ip has been written to a .dat, and redirects the user to in this case google if the ip is in the file. If not, it lets them continue on with signing up to my site.
The code below checks if the control is switched on. I placed it in the index.php
if($One_time_access==1)
{
$fp = fopen("blacklist.dat", "a");
fputs($fp, "\r\n$ip\r\n");
fclose($fp);
}
Then the code below does all the work to figure out the ip, what to ban, etc
<?php
class IpList {
private $iplist = array();
private $ipfile = "";
public function __construct( $list ) {
$contents = array();
$this->ipfile = $list;
$lines = $this->read( $list );
foreach( $lines as $line ) {
$line = trim( $line );
# remove comment and blank lines
if ( empty($line ) ) {
continue;
}
if ( $line[0] == '#' ) {
continue;
}
# remove on line comments
$temp = explode( "#", $line );
$line = trim( $temp[0] );
# create content array
$contents[] = $this->normal($line);
}
$this->iplist = $contents;
}
public function __destruct() {
}
public function __toString() {
return implode(' ',$this->iplist);
}
public function is_inlist( $ip ) {
$retval = false;
foreach( $this->iplist as $ipf ) {
$retval = $this->ip_in_range( $ip, $ipf );
if ($retval === true ) {
$this->range = $ipf;
break;
}
}
return $retval;
}
/*
** public function that returns the ip list array
*/
public function iplist() {
return $this->iplist;
}
/*
*/
public function message() {
return $this->range;
}
public function append( $ip, $comment ) {
return file_put_contents( $this->ipfile, $ip, $comment );
}
public function listname() {
return $this->ipfile;
}
/*
** private function that reads the file into array
*/
private function read( $fname ) {
try {
$file = file( $fname, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
}
catch( Exception $e ) {
throw new Exception( $fname.': '.$e->getmessage() . '\n');
}
return $file;
}
private function ip_in_range( $ip, $range ) {
// return ip_in_range( $ip, $range );
if ( strpos($range, '/') !== false ) {
// IP/NETMASK format
list( $range, $netmask ) = explode( '/', $range, 2 );
if ( strpos( $netmask, '.' ) !== false ) {
// 255.255.255.0 format w/ wildcards
$netmask = str_replace('*', '0', $netmask );
$dnetmask = ip2long( $netmask );
return ((ip2long( $ip ) & $dnetmask) == (ip2long($range) & $dnetmask ));
}
else {
// IP/CIDR format
// insure $range format 0.0.0.0
$r = explode( '.', $range );
while( count( $r ) < 4 ) {
$r[] = '0';
}
for($i = 0; $i < 4; $i++) {
$r[$i] = empty($r[$i]) ? '0': $r[$i];
}
$range = implode( '.', $r );
// build netmask
$dnetmask = ~(pow( 2, ( 32 - $netmask)) - 1);
return ((ip2long($ip) & $dnetmask)==(ip2long($range) & $dnetmask));
}
}
else {
if ( strpos( $range, '*' ) !== false ) {
// 255.255.*.* format
$low = str_replace( '*', '0', $range );
$high = str_replace( '*', '255', $range );
$range = $low.'-'.$high;
}
if ( strpos( $range, '-') !== false ) {
// 128.255.255.0-128.255.255.255 format
list( $low, $high ) = explode( '-', $range, 2 );
$dlow = $this->toLongs( $low );
$dhigh = $this->toLongs( $high );
$dip = $this->toLongs( $ip );
return (($this->compare($dip,$dlow) != -1) && ($this->compare($dip,$dhigh) != 1));
}
}
return ( $ip == $range );
}
private function normal( $range ) {
if ( strpbrk( "*-/", $range ) === False ) {
$range .= "/32";
}
return str_replace( ' ', '', $range );
}
private function toLongs( $ip ) {
# $Ip = $this->expand();
# $Parts = explode(':', $Ip);
$Parts = explode('.', $ip );
$Ip = array('', '');
# for ($i = 0; $i < 4; $i++) {
for ($i = 0; $i < 2; $i++){
$Ip[0] .= str_pad(base_convert($Parts[$i], 16, 2), 16, 0, STR_PAD_LEFT);
}
# for ($i = 4; $i < 8; $i++) {
for ($i = 2; $i < 4; $i++) {
$Ip[1] .= str_pad(base_convert($Parts[$i], 16, 2), 16, 0, STR_PAD_LEFT);
}
return array(base_convert($Ip[0], 2, 10), base_convert($Ip[1], 2, 10));
}
private function compare( $ipdec1, $ipdec2 ) {
if( $ipdec1[0] < $ipdec2[0] ) {
return -1;
}
elseif ( $ipdec1[0] > $ipdec2[0] ) {
return 1;
}
elseif ( $ipdec1[1] < $ipdec2[1] ) {
return -1;
}
elseif ( $ipdec1[1] > $ipdec2[1] ) {
return 1;
}
return 0;
}
}
class IpBlockList {
private $statusid = array( 'negative' => -1, 'neutral' => 0, 'positive' => 1 );
private $whitelist = array();
private $blacklist = array();
private $message = NULL;
private $status = NULL;
public function __construct(
$whitelistfile = 'assets/includes/whitelist.dat',
$blacklistfile = 'assets/includes/blacklist.dat' ) {
$this->whitelistfile = $whitelistfile;
$this->blacklistfile = $blacklistfile;
$this->whitelist = new IpList( $whitelistfile );
$this->blacklist = new IpList( $blacklistfile );
}
public function __destruct() {
}
public function ipPass( $ip ) {
$retval = False;
if ( !filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
throw new Exception( 'Requires valid IPv4 address' );
}
if ( $this->whitelist->is_inlist( $ip ) ) {
// Ip is white listed, so it passes
$retval = True;
$this->message = $ip . " is whitelisted by ".$this->whitelist->message().".";
$this->status = $this->statusid['positive'];
}
else if ( $this->blacklist->is_inlist( $ip ) ) {
$retval = False;
$this->message = $ip . " is blacklisted by ".$this->blacklist->message().".";
$this->status = $this->statusid['negative'];
}
else {
$retval = True;
$this->message = $ip . " is unlisted.";
$this->status = $this->statusid['neutral'];
}
return $retval;
}
public function message() {
return $this->message;
}
public function status() {
return $this->status;
}
public function append( $type, $ip, $comment = "" ) {
if ($type == 'WHITELIST' ) {
$retval = $this->whitelistfile->append( $ip, $comment );
}
elseif( $type == 'BLACKLIST' ) {
$retval = $this->blacklistfile->append( $ip, $comment );
}
else {
$retval = false;
}
}
public function filename( $type, $ip, $comment = "" ) {
if ($type == 'WHITELIST' ) {
$retval = $this->whitelistfile->filename( $ip, $comment );
}
elseif( $type == 'BLACKLIST' ) {
$retval = $this->blacklistfile->filename( $ip, $comment );
}
else {
$retval = false;
}
}
}
$ips = array( $_SERVER['REMOTE_ADDR'],
);
$checklist = new IpBlockList( );
foreach ($ips as $ip ) {
$result = $checklist->ipPass( $ip );
if ( $result ) {
// Continue with page
}
else {
header("Location: https://www.google.co.uk/");
die();
}
}
?>
I want to know:
1. can i write the ips to a text file instead of .dat?
2. is there an easier way to do this?/shorter script?
All help will be appreciated :)

simple php captcha doesn't display image

I'm trying to display a captcha image using simple-php-captcha.php .It's working fine on my local but on the net it doesn't show the captcha image and I think it's because of my url structure.
The url of the page is like this http://test.org/v245/some-url and when I check the captcha image src , It's Look like this src="/simple-php-captcha.php?_CAPTCHA&t=0.11252600+1451561363".
I have tried this http://test.org/simple-php-captcha.php?_CAPTCHA&t=0.11252600+1451561363 But it doesn't make the captcha image .
What's the problem ? Should I change something in htaccess ?
UPDATE:
This is the code of simple-php-captcha.php:
<?php
//
// A simple PHP CAPTCHA script
//
// Copyright 2013 by Cory LaViska for A Beautiful Site, LLC
//
// See readme.md for usage, demo, and licensing info
//
function simple_php_captcha($config = array()) {
// Check for GD library
if( !function_exists('gd_info') ) {
throw new Exception('Required GD library is missing');
}
$bg_path = dirname(__FILE__) . '/backgrounds/';
$font_path = dirname(__FILE__) . '/fonts/';
// Default values
$captcha_config = array(
'code' => '',
'min_length' => 5,
'max_length' => 5,
'backgrounds' => array(
$bg_path . '45-degree-fabric.png',
$bg_path . 'cloth-alike.png',
$bg_path . 'grey-sandbag.png',
$bg_path . 'kinda-jean.png',
$bg_path . 'polyester-lite.png',
$bg_path . 'stitched-wool.png',
$bg_path . 'white-carbon.png',
$bg_path . 'white-wave.png'
),
'fonts' => array(
$font_path . 'times_new_yorker.ttf'
),
'characters' => 'ABCDEFGHJKLMNPRSTUVWXYZabcdefghjkmnprstuvwxyz23456789',
'min_font_size' => 28,
'max_font_size' => 28,
'color' => '#666',
'angle_min' => 0,
'angle_max' => 10,
'shadow' => true,
'shadow_color' => '#fff',
'shadow_offset_x' => -1,
'shadow_offset_y' => 1
);
// Overwrite defaults with custom config values
if( is_array($config) ) {
foreach( $config as $key => $value ) $captcha_config[$key] = $value;
}
// Restrict certain values
if( $captcha_config['min_length'] < 1 ) $captcha_config['min_length'] = 1;
if( $captcha_config['angle_min'] < 0 ) $captcha_config['angle_min'] = 0;
if( $captcha_config['angle_max'] > 10 ) $captcha_config['angle_max'] = 10;
if( $captcha_config['angle_max'] < $captcha_config['angle_min'] ) $captcha_config['angle_max'] = $captcha_config['angle_min'];
if( $captcha_config['min_font_size'] < 10 ) $captcha_config['min_font_size'] = 10;
if( $captcha_config['max_font_size'] < $captcha_config['min_font_size'] ) $captcha_config['max_font_size'] = $captcha_config['min_font_size'];
// Use milliseconds instead of seconds
srand(microtime() * 100);
// Generate CAPTCHA code if not set by user
if( empty($captcha_config['code']) ) {
$captcha_config['code'] = '';
$length = rand($captcha_config['min_length'], $captcha_config['max_length']);
while( strlen($captcha_config['code']) < $length ) {
$captcha_config['code'] .= substr($captcha_config['characters'], rand() % (strlen($captcha_config['characters'])), 1);
}
}
// Generate HTML for image src
$image_src = substr(__FILE__, strlen( realpath($_SERVER['DOCUMENT_ROOT']) )) . '?_CAPTCHA&t=' . urlencode(microtime());
$image_src = '/' . ltrim(preg_replace('/\\\\/', '/', $image_src), '/');
$_SESSION['_CAPTCHA']['config'] = serialize($captcha_config);
return array(
'code' => $captcha_config['code'],
'image_src' => $image_src
);
}
if( !function_exists('hex2rgb') ) {
function hex2rgb($hex_str, $return_string = false, $separator = ',') {
$hex_str = preg_replace("/[^0-9A-Fa-f]/", '', $hex_str); // Gets a proper hex string
$rgb_array = array();
if( strlen($hex_str) == 6 ) {
$color_val = hexdec($hex_str);
$rgb_array['r'] = 0xFF & ($color_val >> 0x10);
$rgb_array['g'] = 0xFF & ($color_val >> 0x8);
$rgb_array['b'] = 0xFF & $color_val;
} elseif( strlen($hex_str) == 3 ) {
$rgb_array['r'] = hexdec(str_repeat(substr($hex_str, 0, 1), 2));
$rgb_array['g'] = hexdec(str_repeat(substr($hex_str, 1, 1), 2));
$rgb_array['b'] = hexdec(str_repeat(substr($hex_str, 2, 1), 2));
} else {
return false;
}
return $return_string ? implode($separator, $rgb_array) : $rgb_array;
}
}
// Draw the image
if( isset($_GET['_CAPTCHA']) ) {
session_start();
$captcha_config = unserialize($_SESSION['_CAPTCHA']['config']);
if( !$captcha_config ){
exit();
}
unset($_SESSION['_CAPTCHA']);
// Use milliseconds instead of seconds
srand(microtime() * 100);
// Pick random background, get info, and start captcha
$background = $captcha_config['backgrounds'][rand(0, count($captcha_config['backgrounds']) -1)];
list($bg_width, $bg_height, $bg_type, $bg_attr) = getimagesize($background);
$captcha = imagecreatefrompng($background);
$color = hex2rgb($captcha_config['color']);
$color = imagecolorallocate($captcha, $color['r'], $color['g'], $color['b']);
// Determine text angle
$angle = rand( $captcha_config['angle_min'], $captcha_config['angle_max'] ) * (rand(0, 1) == 1 ? -1 : 1);
// Select font randomly
$font = $captcha_config['fonts'][rand(0, count($captcha_config['fonts']) - 1)];
// Verify font file exists
if( !file_exists($font) ) throw new Exception('Font file not found: ' . $font);
//Set the font size.
$font_size = rand($captcha_config['min_font_size'], $captcha_config['max_font_size']);
$text_box_size = imagettfbbox($font_size, $angle, $font, $captcha_config['code']);
// Determine text position
$box_width = abs($text_box_size[6] - $text_box_size[2]);
$box_height = abs($text_box_size[5] - $text_box_size[1]);
$text_pos_x_min = 0;
$text_pos_x_max = ($bg_width) - ($box_width);
$text_pos_x = rand($text_pos_x_min, $text_pos_x_max);
$text_pos_y_min = $box_height;
$text_pos_y_max = ($bg_height) - ($box_height / 2);
$text_pos_y = rand($text_pos_y_min, $text_pos_y_max);
// Draw shadow
if( $captcha_config['shadow'] ){
$shadow_color = hex2rgb($captcha_config['shadow_color']);
$shadow_color = imagecolorallocate($captcha, $shadow_color['r'], $shadow_color['g'], $shadow_color['b']);
imagettftext($captcha, $font_size, $angle, $text_pos_x + $captcha_config['shadow_offset_x'], $text_pos_y + $captcha_config['shadow_offset_y'], $shadow_color, $font, $captcha_config['code']);
}
// Draw text
imagettftext($captcha, $font_size, $angle, $text_pos_x, $text_pos_y, $color, $font, $captcha_config['code']);
// Output image
header("Content-type: image/png");
imagepng($captcha);
}
Thanks

Multi-threading a for statement with php

I'm using this following function to check if images exist at their location. Each time the script runs it load about 40 - 50 urls and so its taking long time to load the page. I was thinking of using threading for the "for statement" (at the end of the script) but couldn't find many examples on how to do that. I'm not very familiar with multi-threading with php but i found an example here using popen.
My script:
function get_image_dim($sURL) {
try {
$hSock = # fopen($sURL, 'rb');
if ($hSock) {
while(!feof($hSock)) {
$vData = fread($hSock, 300);
break;
}
fclose($hSock);
if (strpos(' ' . $vData, 'JFIF')>0) {
$vData = substr($vData, 0, 300);
$asResult = unpack('H*',$vData);
$sBytes = $asResult[1];
$width = 0;
$height = 0;
$hex_width = '';
$hex_height = '';
if (strstr($sBytes, 'ffc2')) {
$hex_height = substr($sBytes, strpos($sBytes, 'ffc2') + 10, 4);
$hex_width = substr($sBytes, strpos($sBytes, 'ffc2') + 14, 4);
} else {
$hex_height = substr($sBytes, strpos($sBytes, 'ffc0') + 10, 4);
$hex_width = substr($sBytes, strpos($sBytes, 'ffc0') + 14, 4);
}
$width = hexdec($hex_width);
$height = hexdec($hex_height);
return array('width' => $width, 'height' => $height);
} elseif (strpos(' ' . $vData, 'GIF')>0) {
$vData = substr($vData, 0, 300);
$asResult = unpack('h*',$vData);
$sBytes = $asResult[1];
$sBytesH = substr($sBytes, 16, 4);
$height = hexdec(strrev($sBytesH));
$sBytesW = substr($sBytes, 12, 4);
$width = hexdec(strrev($sBytesW));
return array('width' => $width, 'height' => $height);
} elseif (strpos(' ' . $vData, 'PNG')>0) {
$vDataH = substr($vData, 22, 4);
$asResult = unpack('n',$vDataH);
$height = $asResult[1];
$vDataW = substr($vData, 18, 4);
$asResult = unpack('n',$vDataW);
$width = $asResult[1];
return array('width' => $width, 'height' => $height);
}
}
} catch (Exception $e) {}
return FALSE;
}
for($y=0;$y<= ($image_count-1);$y++){
$dim = get_image_dim($images[$y]);
if (empty($dim)) {
echo $images[$y];
unset($images[$y]);
}
}
$images = array_values($images);
The popen example i found was:
for ($i=0; $i<10; $i++) {
// open ten processes
for ($j=0; $j<10; $j++) {
$pipe[$j] = popen('script.php', 'w');
}
// wait for them to finish
for ($j=0; $j<10; ++$j) {
pclose($pipe[$j]);
}
}
I'm not sure which part of my code has to go in the script.php? I tried moving the whole script but that didn't work?
Any ideas on how can i implement this or if there is a better way to multi thread it? Thanks.
PHP does not have multi-threading natively. You can do it with pthreads, but having a little experience there, I can say with assurance that that is too much for your needs.
Your best bet will be to use curl, you can initiate multiple requests with curl_multi_init. Based off the example on PHP.net, the following may work for your needs:
function curl_multi_callback(Array $urls, $callback, $cache_dir = NULL, $age = 600) {
$return = array();
$conn = array();
$max_age = time()-intval($age);
$mh = curl_multi_init();
if(is_dir($cache_dir)) {
foreach($urls as $i => $url) {
$cache_path = $cache_dir.DIRECTORY_SEPARATOR.sha1($url).'.ser';
if(file_exists($cache_path)) {
$stat = stat($cache_path);
if($stat['atime'] > $max_age) {
$return[$i] = unserialize(file_get_contents($cache_path));
unset($urls[$i]);
} else {
unlink($cache_path);
}
}
}
}
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, 1);
curl_multi_add_handle($mh, $conn[$i]);
}
do {
$status = curl_multi_exec($mh, $active);
// Keep attempting to get info so long as we get info
while (($info = curl_multi_info_read($mh)) !== FALSE) {
// We received information from Multi
if (false !== $info) {
// The connection was successful
$handle = $info['handle'];
// Find the index of the connection in `conn`
$i = array_search($handle, $conn);
if($info['result'] === CURLE_OK) {
// If we found an index and that index is set in the `urls` array
if(false !== $i && isset($urls[$i])) {
$content = curl_multi_getcontent($handle);
$return[$i] = $data = array(
'url' => $urls[$i],
'content' => $content,
'parsed' => call_user_func($callback, $content, $urls[$i]),
);
if(is_dir($cache_dir)) {
file_put_contents($cache_dir.DIRECTORY_SEPARATOR.sha1($urls[$i]).'.ser', serialize($data));
}
}
} else {
// Handle failures how you will
}
// Close, even if a failure
curl_multi_remove_handle($mh, $handle);
unset($conn[$i]);
}
}
} while ($status === CURLM_CALL_MULTI_PERFORM || $active);
// Cleanup and resolve any remaining connections (unlikely)
if(!empty($conn)) {
foreach ($conn as $i => $handle) {
if(isset($urls[$i])) {
$content = curl_multi_getcontent($handle);
$return[$i] = $data = array(
'url' => $urls[$i],
'content' => $content,
'parsed' => call_user_func($callback, $content, $urls[$i]),
);
if(is_dir($cache_dir)) {
file_put_contents($cache_dir.DIRECTORY_SEPARATOR.sha1($urls[$i]).'.ser', serialize($data));
}
}
curl_multi_remove_handle($mh, $handle);
unset($conn[$i]);
}
}
curl_multi_close($mh);
return $return;
}
$return = curl_multi_callback($urls, function($data, $url) {
echo "got $url\n";
return array('some stuff');
}, '/tmp', 30);
//print_r($return);
/*
$url_dims = array(
'url' => 'http://www......',
'content' => raw content
'parsed' => return of get_image_dim
)
*/
Just restructure your original function get_image_dim to consume the raw data and output whatever you are looking for.
This is not a complete function, there may be errors, or idiosyncrasies you need to resolve, but it should serve as a good starting point.
Updated to include caching. This changed a test I was running on 18 URLS from 1 second, to .007 seconds (with cache hits).
Note: you may want to not cache the full request contents, as I did, and just cache the url and the parsed data.

Php WebSocket Handshake

I create a secure websocket server with stream_socket_server.
And i'd like to have a function accept that sequencially get the connections and do the handshake as a blocking access. With chrome, it connects and deconnects and with Firefox it tells me that there's an error with fread.
The snippet is :
$write = null;
$except = null;
$sockets = $this->socket;
#stream_select( $sockets, $write, $except, 0 );
foreach( $sockets as $socket ) {
$resource = #stream_socket_accept( $socket );
if (!$resource) {
return false;
}
$accepts = array( $resource );
#stream_select( $accepts, $write, $except, 0, 1000 );
foreach( $accepts as $accepted ) {
$buffer = '';
$bytes_to_read = 8192;
while ( $chunk = fread( $accepted, $bytes_to_read ) ) {
$buffer .= $chunk;
$status = stream_get_meta_data( $accepted );
$bytes_to_read = $status[ "unread_bytes" ];
if ( strlen( $buffer ) === 1 )
$bytes_to_read = 8192;
}
$response = HandShake::perform( $buffer );
$responseLength = strlen( $response );
for( $written = 0; $written < $responseLength; $written += $fwrite ) {
$fwrite = fwrite( $accepted, substr( $response, $written ) );
if ( ( $fwrite === false ) || ( $fwrite === 0 ) ) {
stream_socket_shutdown( $accepted, STREAM_SHUT_RDWR );
return false;
}
}
}
}
Can you tell me why it doesn't work and transform my snippet ?

Convert binary bytes to string

what im trying to do:
1. uncompress compressed file.
2.insert the uncompressed file bytes into array.
3.convert each byte to chr.
the code:
<?php
$list = file_get_contents('http://www.getlist.xp3.biz/list3'); //get the contents of the compressed file
$list = gzuncompress($list); //Uncompress the file
$bytes = unpack('c*', $list); //unpack the bytes of list into array
$string = implode('', array_map('chr', $bytes)); //convert each byte to chr by implode and array_map functions
echo $string; //print results
?>
this code is almost works.
the results:
http://getlist.xp3.biz/getlist.php
lets take this line for example:
B~12ee397313ba2dd4f27fc1430744e615e4f83a44f9b206fb78fdf9b45dd9dc74fel profanador88's Room ar�7t��Bk
in the end of the line there are some wired chars : ar�7t��Bk
this chars are not text byte, someone(other developer) is converted the bytes and his php file returns the line with more information:
{"ver":"26","id":"12ee397313ba2dd4f27fc1430744e615e4f83a44f9b206fb78fdf9b45dd9dc74f","name":"profanador88's Room","players":"1","max_players":"10","password":false,"country":"ar","latitude":"41.0186004639","longitude":"28.9647006989","distance":1168.7633}
i have the id ,roomname and country code(and the werid chars(=the other info)).
in his line: version,id, name ,players number,max player number,if isset password(boolean),contry code, latitude,longitude and distance.
exactly 7 more.
maybe ar�7t��Bk contains the other information?
i think that the other info is there (100%), i just dont know how to convert the bytes(of the werid chars).
i tried to ask the other developer about this werid chars but there is no answer.
maybe someone know how to convert this binary file into normal string,
maybe this information can help(the note of the other developer):
the list is a compressed binary file
which you can obtain # /list3
it is compressed with zlib deflate
after decompression the format is as follows: (wait a bit must open the source file)
1 byte ; list format version ( currently = 1 )
4 bytes ; skip this, you don't care about them
then follows a list of RoomInfo structures until the end of the file
this is the Roominfo structure:
data.writeShort(ver); //Vrsion Short
data.writeUTF(netID); //ID String
data.writeUTF(name); //ROOMNAME string
data.writeByte(players); //PLAYERS
data.writeByte(maxPlayers); //MaxPlayers
data.writeBoolean(password); //If isset password boolean
data.writeUTF(countryCode); //country code
data.writeFloat(latitude); //Float latitude
data.writeFloat(longitude); //Float longitude
that's all
im using chr function to convert the bytes into big string, hi says that the byte are not only strings, there are bytes that represent:Float,Boolean,Integer,Short.
chr is to bytes that represent string only(and i used it : $string = implode('', array_map('chr', $bytes)); ), there im worng maybe i need to read each byte by foreach without using this shortcut.
my question is:
Does anyon know how to fix the code and make it work(make the php print the other info that missing(the info is there , but in bytes(not of string)))?
UPDATE:
i think that i found the class that converts byte to short/boolean/float/integer ,
now i need that someone explain to me how to use this class (require('class.php')...code here), or someone will try to fix my code with this class(im trying to fix it alone but i still dont know how to use this lib or when i need to use the lib).
the class:
class ByteArray{
private $BytesString;
function ByteArray($bytes = "") {
$this->BytesString = $bytes;
}
function writeBoolean($value = 1) {
$this->BytesString .= $this->writeByte($value, False);
}
function writeByte($value, $noReturning=True) {
if ($noReturning) $this->BytesString .= pack("C", $value);
else return pack("C", $value);
}
function writeBytes($value) {
$this->BytesString .= $value;
}
function writeInt($value) {
$this->BytesString .= pack('N', $value);
}
function writeShort($value) {
$this->BytesString .= pack('n', $value);
}
function writeUTF($value) {
$valueSize = strlen($value);
$this->writeShort($valueSize);
$this->writeUTFBytes($value);
}
function writeUTFBytes($value) {
$this->BytesString .= $value;
}
function length() {
return strlen($this->BytesString);
}
function toString() {
return $this->BytesString;
}
function toPack() {
$value = pack('N', strlen($this->BytesString)+4);
return $value.$this->BytesString;
}
function getSize() {
$value = unpack('N', substr($this->BytesString, 0, 4));
return $value[1];
}
function readBy($Pos) {
$this->BytesString = substr($this->BytesString, $Pos);
return $this->BytesString;
}
function loc($byte) {
$loc = substr($this->BytesString, 0, $byte);
$this->BytesString = substr($this->BytesString, $byte);
return unpack('C', $loc);
}
function readInt() {
$size = unpack('N', substr($this->BytesString, 0, 4)); $size = $size[1];
$this->BytesString = substr($this->BytesString, 4);
return $size;
}
function readUTF() {
$size = unpack('n', substr($this->BytesString, 0, 2)); $size = $size[1];
$string = substr($this->BytesString, 2, $size);
$this->BytesString = substr($this->BytesString, $size + 2);
return $string;
}
function readShort() {
$size = unpack('n', substr($this->BytesString, 0, 2)); $size = $size[1];
$this->BytesString = substr($this->BytesString, 2);
return $size;
}
function readBoolean() {
$loc = unpack('C', substr($this->BytesString, 0, 1)); $loc = $loc[1];
$this->BytesString = substr($this->BytesString, 1);
if ($loc == 1) return True;
else return False;
}
function readByte() {
$byte = unpack('C', substr($this->BytesString, 0, 1)); $byte = $byte[1];
$this->BytesString = substr($this->BytesString, 1);
return $byte;
}
}
UPDATE2:
version 2 of the class, if the first not working
<?php
class ByteArray {
protected $bigEndian = TRUE;
protected $byteArray;
protected $capacity;
protected $limit;
protected $mark;
public $position;
public function __construct($byteArray = '') {
$this->byteArray = $byteArray;
$this->position = 0;
$this->mark = - 1;
$this->init ();
}
private function init() {
$this->capacity = strlen ( $this->byteArray );
$this->limit = $this->capacity;
}
public function _array() {
return $this->byteArray;
}
public function clear() {
$this->limit = $this->capacity;
$this->position = 0;
$this->mark = - 1;
}
private function get($length = null) {
if ($length === null) {
$length = $this->limit - $this->position;
} elseif ($length > $this->bytesAvailable ()) {
throw new Exception ( 'bytesAvailable' );
}
$data = substr ( $this->byteArray, $this->position, $length );
$this->position += $length;
return $data;
}
private function set($bytes) {
$p1 = substr ( $this->byteArray, 0, $this->position );
$p2 = substr ( $this->byteArray, $this->position );
$len = strlen ( $bytes );
if ($len < strlen ( $p2 )) {
$p2 = substr ( $p2, $len );
} else {
$p2 = '';
}
$p1 .= $bytes . $p2;
$this->byteArray = $p1;
$this->position += $len;
$this->init ();
}
public function readBytes($length = -1, $offset = -1) {
$limit = $this->limit;
if ($offset == - 1) {
$offset = $this->position;
}
if ($length == - 1) {
$length = $limit - $offset;
}
if ($length > $limit - $offset) {
return null;
}
return substr ( $this->byteArray, $offset, $length );
}
public function writeBytes($bytes, $offset = 0, $length = 0) {
$len = strlen ( $bytes );
if ($len < 1) {
return;
}
if ($length < 1) {
$length = $len;
}
if ($offset < 1) {
$offset = 0;
}
if ($offset + $length > $len) {
return;
}
$p1 = substr ( $bytes, $offset, $length );
$this->set ( $p1 );
}
public function readBoolean() {
return $this->readByte () != 0;
}
public function writeBoolean($value) {
$this->writeByte ( $value != 0 );
}
public function readByte() {
return ord ( $this->get ( 1 ) );
}
public function readUnsignedByte() {
$data = unpack ( 'C', $this->get ( 1 ) );
return $data [1];
}
public function writeByte($value) {
$data = pack ( 'c', $value );
$this->set ( $data );
}
public function readShort() {
$data = unpack ( $this->bigEndian ? 'n' : 'v', $this->get ( 2 ) );
return $data [1];
}
public function writeShort($value) {
$data = pack ( $this->bigEndian ? 'n' : 'v', $value );
$this->set ( $data );
}
public function readInt() {
$data = unpack ( $this->bigEndian ? 'N' : 'V', $this->get ( 4 ) );
return $data [1];
}
public function writeInt($value) {
$data = pack ( $this->bigEndian ? 'N' : 'V', $value );
$this->set ( $data );
}
public function readFloat() {
$data = unpack ( 'f', $this->get ( 4 ) );
return $data [1];
}
public function writeFloat($value) {
$data = pack ( 'f', $value );
$this->set ( $data );
}
public function readDouble() {
$data = unpack ( 'd', $this->get ( 8 ) );
return $data [1];
}
public function writeDouble($value) {
$data = pack ( 'd', $value );
$this->set ( $data );
}
public function readString() {
$length = $this->readShort ();
$value = $this->get ( $length );
return $value;
}
public function writeString($value) {
$len = strlen ( $value );
$this->writeShort ( $len );
$this->writeStringBytes ( $value );
}
public function writeStringBytes($value) {
$len = strlen ( $value );
$data = pack ( 'a' . $len, $value );
$this->set ( $data );
}
public function readStringBytes($length) {
return $this->get ( $length );
}
public function bytesAvailable() {
return $this->limit - $this->position;
}
public function length() {
return $this->limit;
}
public function __toString() {
return $this->byteArray;
}
public function compress($level = 5) {
$this->byteArray = gzcompress ( $this->byteArray, $level );
$this->init ();
}
public function uncompress($level = 5) {
$this->byteArray = gzuncompress ( $this->byteArray, $level );
$this->init ();
}
}
?>

Categories