Symfony 2.8.8 dump function php7.1 not working - php

Recently I've upgraded my php to 7.1 and symfony to 2.8 and everything works ok but dump function, when I try to use it I get:
Notice: A non well formed numeric value encountered
500 Internal Server Error - ContextErrorException
in vendor/symfony/symfony/src/Symfony/Component/VarDumper/Cloner/VarCloner.php at line 298 -
}
}
self::$hashMask ^= hexdec(substr(spl_object_hash($obj), self::$hashOffset, PHP_INT_SIZE));
}
}
I do not know if it's something related to php configuration or what.

UPDATE it seems to be fixed on Symfony 2.8.10.
Previous answer:
Well, I have found a non pretty nice answer, but it works, so what I've done is copying the class VarCloner.php from Symfony 3.1.3 and changing it on my symfony 2.8, and that worked! So here is the class, I also paste here the one that I tried.
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien#symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Cloner;
/**
* #author Nicolas Grekas <p#tchwork.com>
*/
class VarCloner extends AbstractCloner
{
private static $hashMask = 0;
private static $hashOffset = 0;
/**
* {#inheritdoc}
*/
protected function doClone($var)
{
$useExt = $this->useExt;
$i = 0; // Current iteration position in $queue
$len = 1; // Length of $queue
$pos = 0; // Number of cloned items past the first level
$refsCounter = 0; // Hard references counter
$queue = array(array($var)); // This breadth-first queue is the return value
$arrayRefs = array(); // Map of queue indexes to stub array objects
$hardRefs = array(); // Map of original zval hashes to stub objects
$objRefs = array(); // Map of original object handles to their stub object couterpart
$resRefs = array(); // Map of original resource handles to their stub object couterpart
$values = array(); // Map of stub objects' hashes to original values
$maxItems = $this->maxItems;
$maxString = $this->maxString;
$cookie = (object) array(); // Unique object used to detect hard references
$gid = uniqid(mt_rand(), true); // Unique string used to detect the special $GLOBALS variable
$a = null; // Array cast for nested structures
$stub = null; // Stub capturing the main properties of an original item value
// or null if the original value is used directly
$zval = array( // Main properties of the current value
'type' => null,
'zval_isref' => null,
'zval_hash' => null,
'array_count' => null,
'object_class' => null,
'object_handle' => null,
'resource_type' => null,
);
if (!self::$hashMask) {
self::initHashMask();
}
$hashMask = self::$hashMask;
$hashOffset = self::$hashOffset;
for ($i = 0; $i < $len; ++$i) {
$indexed = true; // Whether the currently iterated array is numerically indexed or not
$j = -1; // Position in the currently iterated array
$fromObjCast = array_keys($queue[$i]);
$fromObjCast = array_keys(array_flip($fromObjCast)) !== $fromObjCast;
$refs = $vals = $fromObjCast ? array_values($queue[$i]) : $queue[$i];
foreach ($queue[$i] as $k => $v) {
// $k is the original key
// $v is the original value or a stub object in case of hard references
if ($k !== ++$j) {
$indexed = false;
}
if ($fromObjCast) {
$k = $j;
}
if ($useExt) {
$zval = symfony_zval_info($k, $refs);
} else {
$refs[$k] = $cookie;
if ($zval['zval_isref'] = $vals[$k] === $cookie) {
$zval['zval_hash'] = $v instanceof Stub ? spl_object_hash($v) : null;
}
$zval['type'] = gettype($v);
}
if ($zval['zval_isref']) {
$vals[$k] = &$stub; // Break hard references to make $queue completely
unset($stub); // independent from the original structure
if (isset($hardRefs[$zval['zval_hash']])) {
$vals[$k] = $useExt ? ($v = $hardRefs[$zval['zval_hash']]) : ($refs[$k] = $v);
if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) {
++$v->value->refCount;
}
++$v->refCount;
continue;
}
}
// Create $stub when the original value $v can not be used directly
// If $v is a nested structure, put that structure in array $a
switch ($zval['type']) {
case 'string':
if (isset($v[0]) && !preg_match('//u', $v)) {
$stub = new Stub();
$stub->type = Stub::TYPE_STRING;
$stub->class = Stub::STRING_BINARY;
if (0 <= $maxString && 0 < $cut = strlen($v) - $maxString) {
$stub->cut = $cut;
$stub->value = substr($v, 0, -$cut);
} else {
$stub->value = $v;
}
} elseif (0 <= $maxString && isset($v[1 + ($maxString >> 2)]) && 0 < $cut = mb_strlen($v, 'UTF-8') - $maxString) {
$stub = new Stub();
$stub->type = Stub::TYPE_STRING;
$stub->class = Stub::STRING_UTF8;
$stub->cut = $cut;
$stub->value = mb_substr($v, 0, $maxString, 'UTF-8');
}
break;
case 'integer':
break;
case 'array':
if ($v) {
$stub = $arrayRefs[$len] = new Stub();
$stub->type = Stub::TYPE_ARRAY;
$stub->class = Stub::ARRAY_ASSOC;
// Copies of $GLOBALS have very strange behavior,
// let's detect them with some black magic
$a = $v;
$a[$gid] = true;
// Happens with copies of $GLOBALS
if (isset($v[$gid])) {
unset($v[$gid]);
$a = array();
foreach ($v as $gk => &$gv) {
$a[$gk] = &$gv;
}
} else {
$a = $v;
}
$stub->value = $zval['array_count'] ?: count($a);
}
break;
case 'object':
if (empty($objRefs[$h = $zval['object_handle'] ?: ($hashMask ^ hexdec(substr(spl_object_hash($v), $hashOffset, PHP_INT_SIZE)))])) {
$stub = new Stub();
$stub->type = Stub::TYPE_OBJECT;
$stub->class = $zval['object_class'] ?: get_class($v);
$stub->value = $v;
$stub->handle = $h;
$a = $this->castObject($stub, 0 < $i);
if ($v !== $stub->value) {
if (Stub::TYPE_OBJECT !== $stub->type || null === $stub->value) {
break;
}
if ($useExt) {
$zval['type'] = $stub->value;
$zval = symfony_zval_info('type', $zval);
$h = $zval['object_handle'];
} else {
$h = $hashMask ^ hexdec(substr(spl_object_hash($stub->value), $hashOffset, PHP_INT_SIZE));
}
$stub->handle = $h;
}
$stub->value = null;
if (0 <= $maxItems && $maxItems <= $pos) {
$stub->cut = count($a);
$a = null;
}
}
if (empty($objRefs[$h])) {
$objRefs[$h] = $stub;
} else {
$stub = $objRefs[$h];
++$stub->refCount;
$a = null;
}
break;
case 'resource':
case 'unknown type':
if (empty($resRefs[$h = (int) $v])) {
$stub = new Stub();
$stub->type = Stub::TYPE_RESOURCE;
$stub->class = $zval['resource_type'] ?: get_resource_type($v);
$stub->value = $v;
$stub->handle = $h;
$a = $this->castResource($stub, 0 < $i);
$stub->value = null;
if (0 <= $maxItems && $maxItems <= $pos) {
$stub->cut = count($a);
$a = null;
}
}
if (empty($resRefs[$h])) {
$resRefs[$h] = $stub;
} else {
$stub = $resRefs[$h];
++$stub->refCount;
$a = null;
}
break;
}
if (isset($stub)) {
if ($zval['zval_isref']) {
if ($useExt) {
$vals[$k] = $hardRefs[$zval['zval_hash']] = $v = new Stub();
$v->value = $stub;
} else {
$refs[$k] = new Stub();
$refs[$k]->value = $stub;
$h = spl_object_hash($refs[$k]);
$vals[$k] = $hardRefs[$h] = &$refs[$k];
$values[$h] = $v;
}
$vals[$k]->handle = ++$refsCounter;
} else {
$vals[$k] = $stub;
}
if ($a) {
if ($i && 0 <= $maxItems) {
$k = count($a);
if ($pos < $maxItems) {
if ($maxItems < $pos += $k) {
$a = array_slice($a, 0, $maxItems - $pos);
if ($stub->cut >= 0) {
$stub->cut += $pos - $maxItems;
}
}
} else {
if ($stub->cut >= 0) {
$stub->cut += $k;
}
$stub = $a = null;
unset($arrayRefs[$len]);
continue;
}
}
$queue[$len] = $a;
$stub->position = $len++;
}
$stub = $a = null;
} elseif ($zval['zval_isref']) {
if ($useExt) {
$vals[$k] = $hardRefs[$zval['zval_hash']] = new Stub();
$vals[$k]->value = $v;
} else {
$refs[$k] = $vals[$k] = new Stub();
$refs[$k]->value = $v;
$h = spl_object_hash($refs[$k]);
$hardRefs[$h] = &$refs[$k];
$values[$h] = $v;
}
$vals[$k]->handle = ++$refsCounter;
}
}
if ($fromObjCast) {
$refs = $vals;
$vals = array();
$j = -1;
foreach ($queue[$i] as $k => $v) {
foreach (array($k => $v) as $a => $v) {
}
if ($a !== $k) {
$vals = (object) $vals;
$vals->{$k} = $refs[++$j];
$vals = (array) $vals;
} else {
$vals[$k] = $refs[++$j];
}
}
}
$queue[$i] = $vals;
if (isset($arrayRefs[$i])) {
if ($indexed) {
$arrayRefs[$i]->class = Stub::ARRAY_INDEXED;
}
unset($arrayRefs[$i]);
}
}
foreach ($values as $h => $v) {
$hardRefs[$h] = $v;
}
return $queue;
}
private static function initHashMask()
{
$obj = (object) array();
self::$hashOffset = 16 - PHP_INT_SIZE;
self::$hashMask = -1;
if (defined('HHVM_VERSION')) {
self::$hashOffset += 16;
} else {
// check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below
$obFuncs = array('ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush');
foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $frame) {
if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && in_array($frame['function'], $obFuncs)) {
$frame['line'] = 0;
break;
}
}
if (!empty($frame['line'])) {
ob_start();
debug_zval_dump($obj);
self::$hashMask = (int) substr(ob_get_clean(), 17);
}
}
self::$hashMask ^= hexdec(substr(spl_object_hash($obj), self::$hashOffset, PHP_INT_SIZE));
}
}
paste it into YourProject/vendor/symfony/symfony/src/Symfony/Component/VarDumper/Cloner/VarCloner.php
so, if someone find a better option, please give it to us! Thanks!!

Related

How to get the maximum possible sum of values of the edges’ endpoints php

The contents of this question have been removed due to a DMCA Takedown request by Codility Limited.
Here is the Simplets PHP solution for the Above question from the Codility test.
<?php
$A = [2,2,1,2];
$B = [1,3,4,4];
$w = [3,5,2,4,1];
$N = 5;
// $A = [1];
// $B = [3];
// $A = [1,3];
// $B = [2,4];
function solution ($N, $A, $B){
if(count($A) != count($B) || !is_int($N) )
{
return false;
}
$V = [];
$vertextCount = [];
foreach($A as $k=>$val){
if(!isset($vertextCount[$val])){
$vertextCount[$val] = 0;
}
$vertextCount[$val] += 1;
}
foreach($B as $k=>$val){
if(!isset($vertextCount[$val])){
$vertextCount[$val] = 0;
}
$vertextCount[$val] += 1;
}
if($vertextCount < $N)
{
$vertextCount[$N] = 0;
}
$VC = $vertextCount;
$tn = $N;
$wightArr = [];
while(count($VC) > 0){
$maxKey = current(array_keys($VC, max($VC)));
$wightArr[$maxKey] = $tn;
unset($VC[$maxKey]);
$tn--;
}
$sum = 0;
foreach($A as $k=>$val){
$sum += $wightArr[$A[$k]] + $wightArr[$B[$k]];
}
return $sum;
}
echo $sum = solution($N, $A, $B);
NOTE:- Tested against the 3 given Examples in the test, Not sure about all the test cases.

php - permutation - possible number

already look around but cant find what i want for PHP.
just say i have a number : 1234 ( can be splitted first into array )
and i want to get how many number combination possible for 2 digits, 3 digits , and 4 digits
for example :
possible 4 digits will be :
1234,1243,1324,1342, and so on. ( i dont know how many more )
possible 2 digits will be :
12,13,14,21,23,24,31,32,34,41,42,43
the closest one i get is :
$p = permutate(array('1','2','3','4'));
$result = array();
foreach($p as $perm) {
$result[]=join("",$perm);
}
$result = array_unique($result);
print join("|", $result);
function permutate($elements, $perm = array(), &$permArray = array()){
if(empty($elements)){
array_push($permArray,$perm); return;
}
for($i=0;$i<=count($elements)-1;$i++){
array_push($perm,$elements[$i]);
$tmp = $elements; array_splice($tmp,$i,1);
permutate($tmp,$perm,$permArray);
array_pop($perm);
}
return $permArray;
}
but how can i edit this so i can display for 3 and 2 digits ?
Thanks
i got what i want
it's from #mudasobwa link. and i edit to what i want.
<?php
$in = array(1,2,3,4,5,6);
$te = power_perms($in);
// print_r($te);
$thou=0;
$hun =0;
$pu = 0;
for($i=0;$i<count($te);$i++)
{
$jm = count($te[$i]);
for($j=0;$j<$jm;$j++)
{
$hsl[$i] = $hsl[$i] . $te[$i][$j];
}
if($hsl[$i] >=100 && $hsl[$i] < 1000 )
{
$ratus[$hun] = intval($hsl[$i]);
$hun = $hun + 1;
}
if($hsl[$i] <100 && $hsl[$i] >=10)
{
$pul[$pu] = intval($hsl[$i]);
$pu = $pu + 1;
}
if($hsl[$i] >=1000 && $hsl[$i] < 10000)
{
$th[$thou] = intval($hsl[$i]);
$thou = $thou + 1;
}
}
$th=array_unique($th);
$pul = array_unique($pul);
$ratus = array_unique($ratus);
sort($ratus);
sort($pul);
sort($th);
print_r($th);
function power_perms($arr) {
$power_set = power_set($arr);
$result = array();
foreach($power_set as $set) {
$perms = perms($set);
$result = array_merge($result,$perms);
}
return $result;
}
function power_set($in,$minLength = 1) {
$count = count($in);
$members = pow(2,$count);
$return = array();
for ($i = 0; $i < $members; $i++) {
$b = sprintf("%0".$count."b",$i);
$out = array();
for ($j = 0; $j < $count; $j++) {
if ($b{$j} == '1') $out[] = $in[$j];
}
if (count($out) >= $minLength) {
$return[] = $out;
}
}
// usort($return,"cmp"); //can sort here by length
return $return;
}
function factorial($int){
if($int < 2) {
return 1;
}
for($f = 2; $int-1 > 1; $f *= $int--);
return $f;
}
function perm($arr, $nth = null) {
if ($nth === null) {
return perms($arr);
}
$result = array();
$length = count($arr);
while ($length--) {
$f = factorial($length);
$p = floor($nth / $f);
$result[] = $arr[$p];
array_delete_by_key($arr, $p);
$nth -= $p * $f;
}
$result = array_merge($result,$arr);
return $result;
}
function perms($arr) {
$p = array();
for ($i=0; $i < factorial(count($arr)); $i++) {
$p[] = perm($arr, $i);
}
return $p;
}
function array_delete_by_key(&$array, $delete_key, $use_old_keys = FALSE) {
unset($array[$delete_key]);
if(!$use_old_keys) {
$array = array_values($array);
}
return TRUE;
}
?>

PHP pack 9 bit int then 10 bit int

I'm trying to write a program in PHP which takes a list of 9 bit ints (0-511) and 10 bit ints (0-1023) and writes them as binary to a file then reads it back. for example:
$dataIn = array(array(275, 863), array(7, 93), array(510, 1010));
$binData = writeBin($dataIn);
$dataOut = readBin($binData);
var_dump($dataIn, $dataOut, $binData);
function writeBin($data) {
$bin = "";
foreach ($data as $d) {
// 9 bit 10 bit
$bin .= pack('SS', $d[0], $d[1]);
}
return $bin;
}
function readBin($bin) {
$bin = str_split($bin, 4);
$data = array();
foreach ($bin as $b) {
$up = unpack('SS', $b); // im only getting 275, 7 and 510 here
$data[] = $up;
}
return $data;
}
But how can i write these to the binary file/string so each section is 19 bits long, and then split it by the 19 bits when reading it back? So a file with 10 of these records in it should only be 190 bits
I solved this issue by writing my own class to write and read differing bit length numbers to binary:
$listLen = 10;
// get an array of 10 random 9 bit ints
$b9s = range(0, 511);
shuffle($b9s);
$b9s = array_slice($b9s, 0, $listLen);
// get an array of 10 random 10 bit ints
$b10s = range(0, 1023);
shuffle($b10s);
$b10s = array_slice($b10s, 0, $listLen);
//build array of input data
$dataIn = array();
for ($i = 0; $i < $listLen; $i++) {
$dataIn[] = array($b9s[$i], $b10s[$i]);
}
//-------
//initialise
$bitFormat = array(9, 10);
$BC = new BinConverter($bitFormat);
//pack
$BC->addData($dataIn);
$binData = $BC->getBin();
//unpack
$BC->setBin($binData);
$dataOut = $BC->getData();
var_dump($dataOut, $binData);
Class BinConverter {
private $bitFormat;
private $maxSectLen;
private $binary;
private $binData;
private $dataOffset;
// $bitFormat = list of bit lengths e.g. array(9, 10)
public function __construct($bitFormat) {
$this->setBitFormat($bitFormat);
$this->binary = "";
$this->binData = "";
$this->dataOffset = 0;
}
// $bitFormat = list of bit lengths e.g. array(9, 10)
public function setBitFormat($bitFormat) {
$bitFormat = array_merge($bitFormat);
$this->bitFormat = $bitFormat;
$this->maxSectLen = 0;
foreach ($this->bitFormat as $bpos => $bf) {
$this->bitFormat[$bpos] = (int) $bf;
$this->maxSectLen += $this->bitFormat[$bpos];
}
}
// $data = list of data sections to convert e.g. array(array(167, 89), array(62, 32), array(325, 975))
public function addData($data) {
foreach ($data as $d) {
$d = array_merge($d);
if (is_array($d) && count($d) != count($this->bitFormat)) {
throw new Exception("Invalid data section");
}
foreach ($d as $dpos => $dbit) {
$dbit = (int) $dbit;
$tbin = decbin($dbit);
if (strlen($tbin) > $this->bitFormat[$dpos]) {
throw new Exception("Data (".$dbit.") too big for ".$this->bitFormat[$dpos]." bit segment");
}
$this->binary .= $this->binPad($tbin, $this->bitFormat[$dpos]);
}
}
}
//returns binary representation of added data
public function getBin() {
$bin = "";
if ($this->binary) {
$bits = str_split($this->binary, 4);
foreach ($bits as $bpos => $bit) {
$bp = bindec($this->binPad($bit, 4));
$bin .= pack('C', $bp);
}
}
return $bin;
}
//$bin = string of binary data
public function setBin($bin) {
if (!is_string($bin)) {
throw new Exception("Invalid binary format");
}
$bdata = "";
foreach (str_split($bin) as $b) {
$unpacked = unpack('C', $b);
$binbit = $this->binPad(decbin($unpacked[1]), 4);
$bdata .= $binbit;
}
$this->binData = $bdata;
}
//returns unpacked data in the current bit format
public function getData() {
$data = array();
$binlen = strlen($this->binData);
if ($binlen) {
$bdata = $this->binData;
$overflow = $binlen % $this->maxSectLen % 4;
$lastbit = substr($bdata, -4);
$overflowBit = substr($lastbit, 0, $overflow);
$binbit = substr($lastbit, $overflow);
$bdata = substr($bdata, 0, -4) . $binbit;
$tdata = str_split($bdata, $this->maxSectLen);
foreach ($tdata as $d) {
if (strlen($d) != $this->maxSectLen) {
throw new Exception("Invalid binary format");
}
$offset = 0;
$ds = array();
foreach ($this->bitFormat as $bf) {
$ds[] = bindec(substr($d, $offset, $bf));
$offset += $bf;
}
$data[] = $ds;
}
}
return $data;
}
//returns unpacked data in the current bit format for (int) $ni number of sections
public function getNextSection($ni = null) {
$data = array();
$binlen = strlen($this->binData);
if ($binlen) {
$n = $ni;
if ($n === null) {
$n = 1;
}
$glen = $n*$this->maxSectLen;
$bdata = substr($this->binData, $this->dataOffset, $glen);
if (strlen($bdata) != $glen) {
throw new Exception("Invalid data format used");
}
$this->dataOffset += $glen;
if ($this->dataOffset+4 > $binlen) {
$overflow = $binlen - $this->dataOffset;
$lastbit = substr($this->binData, -4);
$overflowBit = substr($lastbit, 0, $overflow);
$binbit = substr($lastbit, $overflow);
$bdata = substr($bdata, 0, -(4-$overflow)) . $binbit;
}
$tdata = str_split($bdata, $this->maxSectLen);
foreach ($tdata as $d) {
if (strlen($d) != $this->maxSectLen) {
throw new Exception("Invalid binary format");
}
$offset = 0;
$ds = array();
foreach ($this->bitFormat as $bf) {
$ds[] = bindec(substr($d, $offset, $bf));
$offset += $bf;
}
$data[] = $ds;
}
if ($ni === null) {
return $data[0];
}
}
return $data;
}
private function binPad($var, $a) {
return str_pad($var, $a, '0', STR_PAD_LEFT);
}
}
and an example of how to use multiple bit formats in one file:
$listLen1 = rand(1, 20);
// get an array of 10 random 9 bit ints
$b9s = range(0, 511);
shuffle($b9s);
$b9s = array_slice($b9s, 0, $listLen1);
// get an array of 10 random 10 bit ints
$b10s = range(0, 1023);
shuffle($b10s);
$b10s = array_slice($b10s, 0, $listLen1);
//build array of input data
$dataIn1 = array();
for ($i = 0; $i < $listLen1; $i++) {
$dataIn1[] = array($b9s[$i], $b10s[$i]);
}
$listLen2 = rand(1, 20);
// get an array of 10 random 16 bit ints
$b16s = range(0, 65535);
shuffle($b16s);
$b16s = array_slice($b16s, 0, $listLen2);
// get an array of 10 random 8 bit ints
$b8s = range(0, 255);
shuffle($b8s);
$b8s = array_slice($b8s, 0, $listLen2);
// get an array of 10 random 14 bit ints
$b14s = range(0, 16383);
shuffle($b14s);
$b14s = array_slice($b14s, 0, $listLen2);
$dataIn2 = array();
for ($i = 0; $i < $listLen2; $i++) {
$dataIn2[] = array($b16s[$i], $b8s[$i], $b14s[$i]);
}
//-------
$file = './binfile.bf';
//initialise
$bitFormat1 = array(9, 10);
$bitFormat2 = array(16, 8, 14);
$BC = new BinConvert($bitFormat1);
//pack
$BC->addData($dataIn1);
$BC->setBitFormat($bitFormat2);
$BC->addData($dataIn2);
$binData = $BC->getBin();
file_put_contents($file,$binData);
//unpack
$binData = file_get_contents($file);
$BC->setBin($binData);
$BC->setBitFormat($bitFormat1);
$dataOut1 = $BC->getNextSection($listLen1);
$BC->setBitFormat($bitFormat2);
$dataOut2 = $BC->getNextSection($listLen2);
var_dump($dataOut1, $dataOut2, $binData);

PDF to XML conversion using PHP

I need help to convert PDF to XML using PHP.
There are some sites which claims to do so. But they charge for that.
I have to write my own code in PHP for that.
Being a novice in PHP I don't know how to approach this task.
So if anyone had worked on it plz help me with this.
Any help would be highly appreciated.
PDFX does PDF-to-XML conversion and it's free to use. It might be helpful in your case as it can extract things like images and captions separately.
Example input/output can be found here.
The usage page includes a simple PHP client example.
(Disclosure: It is my system.)
PDF2HTML will convert to HTML or XML (using the -xml flag), but the result is a bit of a mess. You get lots of small chunks of information about the location of fragments of text. No good of you want to extract paragraphs or sections of text. You may be able to isolate images with a suitable XPath?
If you do need paragraphs or sections of text, it appears you have to do it heuristically. Geert's blog has an interesting approach:
Isolating text runs in different zones (like header and footer)
Gathering text runs on the same ‘line’ (ignoring columns here)
Translate indentation to hierarchy (helps finding lists, provides bare table/column handling)
Merging of lines to build paragraphs
You can use this class to pars pdf into string and than work this it =)
<?php class PDF2Text2 {
var $multibyte = 4; //
var $convertquotes = ENT_QUOTES; //
var $showprogress = true; //
var $filename = '';
var $decodedtext = '';
function setFilename($filename) {
// Reset
$this->decodedtext = '';
$this->filename = $filename;
}
function output($echo = false) {
if($echo) echo $this->decodedtext;
else return $this->decodedtext;
}
function setUnicode($input) {
// 4 for unicode. But 2 should work in most cases just fine
if($input == true) $this->multibyte = 4;
else $this->multibyte = 2;
}
function decodePDF() {
// Read the data from pdf file
$infile = #file_get_contents($this->filename, FILE_BINARY);
if (empty($infile))
return "";
// Get all text data.
$transformations = array();
$texts = array();
// Get the list of all objects.
preg_match_all("#obj[\n|\r](.*)endobj[\n|\r]#ismU", $infile . "endobj\r", $objects);
$objects = #$objects[1];
// Select objects with streams.
for ($i = 0; $i < count($objects); $i++) {
$currentObject = $objects[$i];
// Prevent time-out
#set_time_limit ();
if($this->showprogress) { // echo ". ";
flush(); ob_flush();
}
// Check if an object includes data stream.
if (preg_match("#stream[\n|\r](.*)endstream[\n|\r]#ismU", $currentObject . "endstream\r", $stream )) {
$stream = ltrim($stream[1]);
// Check object parameters and look for text data.
$options = $this->getObjectOptions($currentObject);
if (!(empty($options["Length1"]) && empty($options["Type"]) && empty($options["Subtype"])) )
if ( $options["Image"] && $options["Subtype"] )
if (!(empty($options["Length1"]) && empty($options["Subtype"])) )
continue;
// Hack, length doesnt always seem to be correct
unset($options["Length"]);
// So, we have text data. Decode it.
$data = $this->getDecodedStream($stream, $options);
if (strlen($data)) {
if (preg_match_all("#BT[\n|\r](.*)ET[\n|\r]#ismU", $data . "ET\r", $textContainers)) {
$textContainers = #$textContainers[1];
$this->getDirtyTexts($texts, $textContainers);
} else
$this->getCharTransformations($transformations, $data);
}
}
}
// Analyze text blocks taking into account character transformations and return results.
$this->decodedtext = $this->getTextUsingTransformations($texts, $transformations);
}
function decodeAsciiHex($input) {
$output = "";
$isOdd = true;
$isComment = false;
for($i = 0, $codeHigh = -1; $i < strlen($input) && $input[$i] != '>'; $i++) {
$c = $input[$i];
if($isComment) {
if ($c == '\r' || $c == '\n')
$isComment = false;
continue;
}
switch($c) {
case '\0': case '\t': case '\r': case '\f': case '\n': case ' ': break;
case '%':
$isComment = true;
break;
default:
$code = hexdec($c);
if($code === 0 && $c != '0')
return "";
if($isOdd)
$codeHigh = $code;
else
$output .= chr($codeHigh * 16 + $code);
$isOdd = !$isOdd;
break;
}
}
if($input[$i] != '>')
return "";
if($isOdd)
$output .= chr($codeHigh * 16);
return $output;
}
function decodeAscii85($input) {
$output = "";
$isComment = false;
$ords = array();
for($i = 0, $state = 0; $i < strlen($input) && $input[$i] != '~'; $i++) {
$c = $input[$i];
if($isComment) {
if ($c == '\r' || $c == '\n')
$isComment = false;
continue;
}
if ($c == '\0' || $c == '\t' || $c == '\r' || $c == '\f' || $c == '\n' || $c == ' ')
continue;
if ($c == '%') {
$isComment = true;
continue;
}
if ($c == 'z' && $state === 0) {
$output .= str_repeat(chr(0), 4);
continue;
}
if ($c < '!' || $c > 'u')
return "";
$code = ord($input[$i]) & 0xff;
$ords[$state++] = $code - ord('!');
if ($state == 5) {
$state = 0;
for ($sum = 0, $j = 0; $j < 5; $j++)
$sum = $sum * 85 + $ords[$j];
for ($j = 3; $j >= 0; $j--)
$output .= chr($sum >> ($j * 8));
}
}
if ($state === 1)
return "";
elseif ($state > 1) {
for ($i = 0, $sum = 0; $i < $state; $i++)
$sum += ($ords[$i] + ($i == $state - 1)) * pow(85, 4 - $i);
for ($i = 0; $i < $state - 1; $i++) {
try {
if(false == ($o = chr($sum >> ((3 - $i) * 8)))) {
throw new Exception('Error');
}
$output .= $o;
} catch (Exception $e) { /*Dont do anything*/ }
}
}
return $output;
}
function decodeFlate($data) {
return #gzuncompress($data);
}
function getObjectOptions($object) {
$options = array();
if (preg_match("#<<(.*)>>#ismU", $object, $options)) {
$options = explode("/", $options[1]);
#array_shift($options);
$o = array();
for ($j = 0; $j < #count($options); $j++) {
$options[$j] = preg_replace("#\s+#", " ", trim($options[$j]));
if (strpos($options[$j], " ") !== false) {
$parts = explode(" ", $options[$j]);
$o[$parts[0]] = $parts[1];
} else
$o[$options[$j]] = true;
}
$options = $o;
unset($o);
}
return $options;
}
function getDecodedStream($stream, $options) {
$data = "";
if (empty($options["Filter"]))
$data = $stream;
else {
$length = !empty($options["Length"]) ? $options["Length"] : strlen($stream);
$_stream = substr($stream, 0, $length);
foreach ($options as $key => $value) {
if ($key == "ASCIIHexDecode")
$_stream = $this->decodeAsciiHex($_stream);
elseif ($key == "ASCII85Decode")
$_stream = $this->decodeAscii85($_stream);
elseif ($key == "FlateDecode")
$_stream = $this->decodeFlate($_stream);
elseif ($key == "Crypt") { // TO DO
}
}
$data = $_stream;
}
return $data;
}
function getDirtyTexts(&$texts, $textContainers) {
for ($j = 0; $j < count($textContainers); $j++) {
if (preg_match_all("#\[(.*)\]\s*TJ[\n|\r]#ismU", $textContainers[$j], $parts))
$texts = array_merge($texts, array(#implode('', $parts[1])));
elseif (preg_match_all("#T[d|w|m|f]\s*(\(.*\))\s*Tj[\n|\r]#ismU", $textContainers[$j], $parts))
$texts = array_merge($texts, array(#implode('', $parts[1])));
elseif (preg_match_all("#T[d|w|m|f]\s*(\[.*\])\s*Tj[\n|\r]#ismU", $textContainers[$j], $parts))
$texts = array_merge($texts, array(#implode('', $parts[1])));
}
}
function getCharTransformations(&$transformations, $stream) {
preg_match_all("#([0-9]+)\s+beginbfchar(.*)endbfchar#ismU", $stream, $chars, PREG_SET_ORDER);
preg_match_all("#([0-9]+)\s+beginbfrange(.*)endbfrange#ismU", $stream, $ranges, PREG_SET_ORDER);
for ($j = 0; $j < count($chars); $j++) {
$count = $chars[$j][1];
$current = explode("\n", trim($chars[$j][2]));
for ($k = 0; $k < $count && $k < count($current); $k++) {
if (preg_match("#<([0-9a-f]{2,4})>\s+<([0-9a-f]{4,512})>#is", trim($current[$k]), $map))
$transformations[str_pad($map[1], 4, "0")] = $map[2];
}
}
for ($j = 0; $j < count($ranges); $j++) {
$count = $ranges[$j][1];
$current = explode("\n", trim($ranges[$j][2]));
for ($k = 0; $k < $count && $k < count($current); $k++) {
if (preg_match("#<([0-9a-f]{4})>\s+<([0-9a-f]{4})>\s+<([0-9a-f]{4})>#is", trim($current[$k]), $map)) {
$from = hexdec($map[1]);
$to = hexdec($map[2]);
$_from = hexdec($map[3]);
for ($m = $from, $n = 0; $m <= $to; $m++, $n++)
$transformations[sprintf("%04X", $m)] = sprintf("%04X", $_from + $n);
} elseif (preg_match("#<([0-9a-f]{4})>\s+<([0-9a-f]{4})>\s+\[(.*)\]#ismU", trim($current[$k]), $map)) {
$from = hexdec($map[1]);
$to = hexdec($map[2]);
$parts = preg_split("#\s+#", trim($map[3]));
for ($m = $from, $n = 0; $m <= $to && $n < count($parts); $m++, $n++)
$transformations[sprintf("%04X", $m)] = sprintf("%04X", hexdec($parts[$n]));
}
}
}
}
function getTextUsingTransformations($texts, $transformations) {
$document = "";
for ($i = 0; $i < count($texts); $i++) {
$isHex = false;
$isPlain = false;
$hex = "";
$plain = "";
for ($j = 0; $j < strlen($texts[$i]); $j++) {
$c = $texts[$i][$j];
switch($c) {
case "<":
$hex = "";
$isHex = true;
$isPlain = false;
break;
case ">":
$hexs = str_split($hex, $this->multibyte); // 2 or 4 (UTF8 or ISO)
for ($k = 0; $k < count($hexs); $k++) {
$chex = str_pad($hexs[$k], 4, "0"); // Add tailing zero
if (isset($transformations[$chex]))
$chex = $transformations[$chex];
$document .= html_entity_decode("&#x".$chex.";");
}
$isHex = false;
break;
case "(":
$plain = "";
$isPlain = true;
$isHex = false;
break;
case ")":
$document .= $plain;
$isPlain = false;
break;
case "\\":
$c2 = $texts[$i][$j + 1];
if (in_array($c2, array("\\", "(", ")"))) $plain .= $c2;
elseif ($c2 == "n") $plain .= '\n';
elseif ($c2 == "r") $plain .= '\r';
elseif ($c2 == "t") $plain .= '\t';
elseif ($c2 == "b") $plain .= '\b';
elseif ($c2 == "f") $plain .= '\f';
elseif ($c2 >= '0' && $c2 <= '9') {
$oct = preg_replace("#[^0-9]#", "", substr($texts[$i], $j + 1, 3));
$j += strlen($oct) - 1;
$plain .= html_entity_decode("&#".octdec($oct).";", $this->convertquotes);
}
$j++;
break;
default:
if ($isHex)
$hex .= $c;
elseif ($isPlain)
$plain .= $c;
break;
}
}
$document .= "\n";
}
return $document;
}}?>

Solve Matrix with PHP

I want to solve a matrix with PHP. For example, if I have three points: (x0, y0), (x1, y1) and (x2, y2), I want to know what p[0], p[1] and p[2] is in y = p[2]*x^2 + p[1]*x^1 + p[0]*x^0, valid for all those points. If n points are given, I want to solve y = p[n] * x^n + p[n-1] * x^(n-1) + ... + p[0] * x^0. What I have at this point, is this:
<?php
$system = new EQ();
$system->add(1, 2);
$system->add(4, 5);
$system->solvePn(0);
class EQ {
private $points = array();
public function add($x, $y) {
$this->points[] = array($x, $y);
}
public function solvePn($n) {
// Solve p[n]
// So eliminate p[m], p[m-1], ..., p[n+1], p[n-1], ..., p[1], p[0]
$m = count($this->points);
$a = $m;
// Eliminate p[a]
if ($a != $n) {
}
$a--;
}
}
?>
But now I don't know what to do next.
Thanks davin and Roman. I used Lagrange for it, and it works fine now. For example, if there are 3 points given (1,1), (2,3), (3,27), the class will use Lagrange to calculate a polynomial approximation. Now you can call $system->f(4) to calculate the y-value for x=4 on this polynome.
<?php
$system = new EQ();
$system->add(1, 1);
$system->add(2, 3);
$system->add(3, 27);
echo $system->f(4);
class EQ {
private $points = array();
private $formula = NULL;
public function add($x, $y) {
$this->points[] = array($x, $y);
}
public function lz($z) {
$point = $this->points[$z];
// Get the x and y value of this point
$x = $point[0];
$y = $point[1];
// Now get all points except these and build the formula
$index = 0;
$above = '';
$below = 1;
foreach ($this->points as $point) {
if ($index != $z) {
$xp = $point[0];
$yp = $point[1];
$above .= '(x-' . $xp . ')';
$below *= ($x - $xp);
}
$index++;
}
$factor = $y / $below;
$above = ungroup($above);
foreach ($above as $degree=>$subfactor) {
$above[$degree] = $subfactor * $factor;
}
return $above;
}
public function f($x) {
if ($this->formula === NULL) $this->L();
$formula = $this->formula;
$val = 0;
foreach ($formula as $degree=>$factor) {
$subval = $factor * pow($x, $degree);
$val += $subval;
}
return $val;
}
public function L() {
$n = count($this->points);
$formula = array();
for ($z = 0; $z < $n; $z++) {
$l = $this->lz($z);
foreach ($l as $degree=>$factor) {
$formula[$degree] += $factor;
}
}
$this->formula = $formula;
return $formula;
}
}
// Transform a group-formula to a list with terms
// #example (x-1)*(x-2)
function ungroup($formula) {
preg_match_all('/\(([^)]{1,})\)/', $formula, $matches);
$groups = $matches[1];
$factorTerms = getTerms(reset($groups));
while (key($groups) < count($groups) - 1) {
next($groups);
$terms = getTerms(current($groups));
$newTerms = array();
foreach ($terms as $term) {
foreach ($factorTerms as $factorTerm) {
$degree = getDegree($term) + getDegree($factorTerm);
$factor = getFactor($term) * getFactor($factorTerm);
$newTerm = '';
if ($factor != 1) $newTerm = ($factor == -1?'-':$factor);
if ($degree != 0) $newTerm .= 'x' . ($degree == 1?'':'^' . $degree);
if (strlen($newTerm) == 0) $newTerm = '0';
$newTerms[] = $newTerm;
}
}
$factorTerms = $newTerms;
}
$terms = array();
foreach ($factorTerms as $term) {
$degree = getDegree($term);
$factor = getFactor($term);
$terms[$degree] += $factor;
}
return $terms;
}
function getFactor($term) {
if (strpos($term, 'x') !== false) {
$pattern = '/([0-9\-]{1,})[\*]?x/';
preg_match($pattern, $term, $matches);
if (count($matches) == 2) {
$n = $matches[1];
if ($n === '-') return -1;
return $n;
}
return 1;
}
return $term;
}
function getDegree($term) {
if (strpos($term, 'x') !== false) {
$pattern = '/x\^([0-9\-]{1,})/';
preg_match($pattern, $term, $matches);
if (count($matches) == 2) {
return $matches[1];
}
return 1;
}
return 0;
}
function getTerms($group) {
$group = str_replace('-', '+-', $group);
$group = preg_replace('/\+{1,}/', '+', $group);
$terms = explode('+', $group);
return $terms;
}
?>

Categories