?
Solved

Removing __PHP_Incomplete_Class Object

Posted on 2009-03-31
15
Medium Priority
?
1,963 Views
Last Modified: 2013-12-13
i am trying to run a report on a sunshop shopping cart table
the data is base 64 endoded and serialized
i get the following result after doing a base64decode and unserialize
__PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] => item [id] => 20 [quantity] => 1 [options] => Array ( ) [regid] => )
i am mainly looking for item id and quantitiy which is in there
my question is this
how do i remove the __PHP_Incomplete_Class Object error when i dont know the original class name
the code blow simply dumps the data on the screen and row[4] is the problem string
 while($row=mysql_fetch_array($result)) 
   {
       $return[] = $row;
       echo("  OrderID - ");
       print_r($row[1]);
       echo("  ProductID - ");
       print_r($row[2]);
       echo("  Price - ");
       print_r($row[3]);
       echo("  Data Array - "); 
       $product_array = unserialize(base64_decode($row[4])); 
       echo nl2br("\n"); 
       echo("  Trying to Unserialize ");
       echo nl2br("\n");
       print_r($product_array);
 
   }

Open in new window

0
Comment
Question by:gevensen
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 7
15 Comments
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 24044315
Could you supply a $row[4] value. Don't touch it. Simply echo it to a file and upload it.

If you echo it to your browser, copy and paste it from the view-source page, not the rendered output.


0
 

Author Comment

by:gevensen
ID: 24044363
the endcoed serialized value is here:

Tzo0OiJpdGVtIjo0OntzOjI6ImlkIjtpOjIwO3M6ODoicXVhbnRpdHkiO2Q6MTtzOjc6Im9wdGlvbnMiO2E6MDp7fXM6NToicmVnaWQiO3M6MDoiIjt9
0
 

Author Comment

by:gevensen
ID: 24044388
structure is text
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 40

Expert Comment

by:Richard Quadling
ID: 24044455
OK. So decoded that becomes ...

O:4:"item":4:{s:2:"id";i:20;s:8:"quantity";d:1;s:7:"options";a:0:{}s:5:"regid";s:0:"";}

And as you right point out ...

var_dump(unserialize(base64_decode('...')));

outputs ...

object(__PHP_Incomplete_Class)#1 (5) {
  ["__PHP_Incomplete_Class_Name"]=>
  string(4) "item"
  ["id"]=>
  int(20)
  ["quantity"]=>
  float(1)
  ["options"]=>
  array(0) {
  }
  ["regid"]=>
  string(0) ""
}



http://docs.php.net/unserialize shows you how this happens. The serialized data does contain the class info, so you can know where it came from.

You can use the unserialize_callback_func setting to help out here (see the snippet below).

At a complete minimum, the following additional PHP code will fix the problem ...

class item
  {
  }


With that uncommented, the output changes from ...

The class item needs to be available.
PHP Warning:  unserialize(): Function mycallback() hasn't defined the class it was called for in C:\tun.php on line 16
object(__PHP_Incomplete_Class)#1 (5) {
  ["__PHP_Incomplete_Class_Name"]=>
  string(4) "item"
  ["id"]=>
  int(20)
  ["quantity"]=>
  float(1)
  ["options"]=>
  array(0) {
  }
  ["regid"]=>
  string(0) ""
}

to ...

object(item)#1 (4) {
  ["id"]=>
  int(20)
  ["quantity"]=>
  float(1)
  ["options"]=>
  array(0) {
  }
  ["regid"]=>
  string(0) ""
}



<?php
ini_set('unserialize_callback_func', 'mycallback'); // set your callback_function
 
function mycallback($classname) 
	{
	echo "The class $classname needs to be available.\n";
	}
 
/* //uncomment to fix the problem
class item
	{
	}
*/
 
var_dump(unserialize(base64_decode('Tzo0OiJpdGVtIjo0OntzOjI6ImlkIjtpOjIwO3M6ODoicXVhbnRpdHkiO2Q6MTtzOjc6Im9wdGlvbnMiO2E6MDp7fXM6NToicmVnaWQiO3M6MDoiIjt9')));

Open in new window

0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 24044470
In the callback, I would do use the $classname variable to require_once the appropriate class file.

function mycallback($classname)
      {
      require_once "classes_$classname.inc";
      }


sort of thing.
0
 

Author Comment

by:gevensen
ID: 24044557
im still fairly new to php although i have done some c++ a few years back and i did see the unserialize tutorial in php.net but something is not clicking with me

i see the uncomment to fix but what do i declare my class item as and where do i put the

function mycallback($classname)
      {
      require_once "classes_$classname.inc";
      }

btw i really do appreciate the help this one has been making me a little batty
<?php
ini_set('unserialize_callback_func', 'mycallback'); // set your callback_function
 
function mycallback($classname) 
        {
        echo "The class $classname needs to be available.\n";
        }
 
/* //uncomment to fix the problem
class item
        {
        }
*/
 
var_dump(unserialize(base64_decode('Tzo0OiJpdGVtIjo0OntzOjI6ImlkIjtpOjIwO3M6ODoicXVhbnRpdHkiO2Q6MTtzOjc6Im9wdGlvbnMiO2E6MDp7fXM6NToicmVnaWQiO3M6MDoiIjt9')));

Open in new window

0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 24044636
I assume the class is already defined somewhere as it was serialized before putting it into the DB.

All I can say is that it is called item. The name of the file containing that ... I don't know.

What code wrote to the DB?
0
 

Author Comment

by:gevensen
ID: 24044803
thats the hard part
i cant get any info from sunshop, they refuse to answer any questions
and they dont have any good reports either
so im not sure where the class is declared
is there a way to create a phony class just to strip away the info i need?
0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 24047302
Yes ...

class info{}

If you look at comment 24044455, you will see the proof.

But having the class exist, you get an object which is class item with just the properties you've retrieved.

Do you not have access to the rest of the code?
0
 

Author Comment

by:gevensen
ID: 24048997
ok im not as dense as i thought i found a way by googling some of the code you supplied there was a similar example on http://php.nusa.net.id/manual/en/function.unserialize.php
the unknown php object is gone
now i simply get 2 errors
any idea how to get rid of them?

Notice: Undefined variable: row in C:\wamp\www\phptesting\datadump3.php on line 2
OrderID - 10001 Data Array -

item Object ( [id] => 20 [quantity] => 1 [options] => Array ( ) [regid] => )

OrderID - 10004 Data Array -
Fatal error: Cannot redeclare class item in C:\wamp\www\phptesting\datadump3.php(13) : eval()'d code on line 1

<?php
$serializedData=$row[4];
//declare the unknown object
 class MyClass {}
   $object = unserialize($serializedData);
//declare the unserialize function   
  function unserializeUnknownObject($text)
   {
       $matches = Array();
       preg_match_all('/O:(\d)*:"([^":]*)":/', $text, $matches);
       foreach ($matches[2] as $class)
       {
           eval('class '.$class.' { }');
       }
       return unserialize($text);
   }
$object = unserializeUnknownObject($serializedData);
 
$abs_path = dirname(dirname(__FILE__));
include $abs_path.'\sunshop_reports\include\config.php';
 
// include $abs_path.'\phptesting\include\phperrorfunction.php';
// Connects to your Database
$connection=mysql_connect($servername, $dbusername, $dbpassword) or die(mysql_error());
mysql_select_db($dbname) or die(mysql_error());
$sql_query=" SELECT * FROM `ss_orders_products` LIMIT 0 , 30";
$result=mysql_query($sql_query,$connection);
if (!$result)
{ 
die('Invalid query: ' . mysql_error());
}
 $session_data = array();
   while($row=mysql_fetch_array($result)) 
   {
       $return[] = $row;
       echo("  OrderID - ");
       print_r($row[1]);
       echo("  Data Array - "); 
       $pulledata=($row[4]);  
       $session_data = base64_decode($row[4]);
       $decodedtext=unserializeUnknownObject($session_data);
       echo nl2br("\n");  
       echo nl2br("\n"); 
       print_r($decodedtext);
       echo nl2br("\n"); 
       echo nl2br("\n");
   }
 
 
?> 

Open in new window

0
 
LVL 40

Accepted Solution

by:
Richard Quadling earned 2000 total points
ID: 24049225
What is line 2 all about? I think it is a carry over from previous edits.

The code you are using to create the class doesn't check to see if it already exists.

Try changing ...

eval('class '.$class.' { }');

to

if (!class_exists($class, False)) {
   eval('class '.$class.' { }');
}

0
 

Author Comment

by:gevensen
ID: 24049290
yer a genius that dumps all

i still get

Notice: Undefined variable: serializedData in C:\wamp\www\phptesting\include\phperrorclass.php on line 3

Notice: Undefined variable: serializedData in C:\wamp\www\phptesting\include\phperrorfunction.php on line 14

im assuming that comes from $serializedData in

class MyClass {}
   $object = unserialize($serializedData);

any ideas on that before i close this out?

0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 24049729
No idea what you are doing there.

Can you put up the all the code.
0
 

Author Comment

by:gevensen
ID: 24049861
the errors come on the 1st 2 lines only saying $serializedData  is an undefined variable
it then proceeds without error and prints all the class objects to the screen

this is just a step to debug it before i pull the object data and write it to a new table and join it in a sql query to create my desired report

the whole exercise here is to pull quan and item id out so i can write that and a few other simple items to a new table

the printing to the screen is just a visual thing for my benefit so i can see whats happening
// the includes
// include_once 'include\phperrorclass.php';
<?php
   class MyClass {}
   $object = unserialize($serializedData);
?>
// include_once 'include\phperrorfunction.php';
<?php
   function unserializeUnknownObject($text)
   {
       $matches = Array();
       preg_match_all('/O:(\d)*:"([^":]*)":/', $text, $matches);
       foreach ($matches[2] as $class)
       {
       if (!class_exists($class, False)) {
 					  eval('class '.$class.' { }');
											}
       }
       return unserialize($text);
   }
   $object = unserializeUnknownObject($serializedData);
?>
// the code that calls the function
 
<?php
//declare the unknown object
include_once 'include\phperrorclass.php';
include_once 'include\phperrorfunction.php';
//declare the unserialize function   
$abs_path = dirname(dirname(__FILE__));
include $abs_path.'\sunshop_reports\include\config.php';
 
// include $abs_path.'\phptesting\include\phperrorfunction.php';
// Connects to your Database
$connection=mysql_connect($servername, $dbusername, $dbpassword) or die(mysql_error());
mysql_select_db($dbname) or die(mysql_error());
$sql_query=" SELECT * FROM `ss_orders_products` LIMIT 0 , 30";
$result=mysql_query($sql_query,$connection);
if (!$result)
{ 
die('Invalid query: ' . mysql_error());
}
 $session_data = array();
   while($row=mysql_fetch_array($result)) 
   {
       $return[] = $row;
       echo("  OrderID - ");
       print_r($row[1]);
       echo("  Data Array - "); 
       $pulledata=($row[4]);  
       $session_data = base64_decode($row[4]);
       $decodedtext=unserializeUnknownObject($session_data);
       echo nl2br("\n"); 
       print_r($decodedtext);
       echo nl2br("\n"); 
       echo nl2br("\n");
   }
 
 
?> 

Open in new window

0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 24049934
I'm not following your code.

Your initial code was working just fine.

Nearly.

Go back to my code and replace ...

function mycallback($classname)
        {
        echo "The class $classname needs to be available.\n";
        }

with ...


function mycallback($class)
        {
        if (!class_exists($class, False))
                {
                eval('class '.$class.' { }');
                }
        }

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
These days socially coordinated efforts have turned into a critical requirement for enterprises.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Suggested Courses

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question