I have a custom class in PHP. If I serialize the class and save it to a text file, I can't unserialize it later in another php file. When I try to call the class functions on the object I get
Call to a member function [functioname()] on a non-object...
I do include the class in both php files.
PHP File 1:
$myobject = new myclass();
$temp = serialize($myobject);
file_put_contents('serializetest.txt', $temp);
PHP File 2:
$s = file_get_contents('serializetest.txt');
$newobject = unserialize($s);
Is there some reason why a serialized class would unserialize properly?
Update
If I create an object and use it's main function I can unserialize the unrelated saved object. The class searches for criminal cases. Even though the two objects are entirely different, once I create and use the new object I can suddenly unserialize saved past objects. i.e. The below works but if I removed the first 3 lines of code it wouldn't.
$tempcase = new Expungement();
$tempcase->searchCase('4B02305986','Public',true,false);
echo "Case Number 1: " . $tempcase->caseno;
$s = file_get_contents('serializetest.txt');
echo "Serialized Data: " . $s;
$newcase = unserialize($s);
echo "Case Number 2: " . $newcase->caseno;
Have you checked content of "serializetest.txt" and value of $s?
Are file 1 and file 2 in the same directory?
Sometimes unserialize doesn't work good if you have "complicated" classes with many crossreferences.
Related
got a script which has string variables that represent data fields like they are in the database. because this project is a complete mess this is a stage in cleaning it up and not having to rewrite the field name in numerous locations.
so one script 'DataKeys.php' will have variables set to field names.
//results from query1
$keyField1 = 'field1';
$keyField2 = 'field2';
these two vars above is only a snippet of a much longer list.
I want to access this file and use these vars when I am formatting the data to be more friendly for the front end. this script is being accessed in a class however the fields, $keyField1, defined in the script is not being found in the class. I did have the actual string there but I think single access point would be best so when I make future changes I don't need search the whole project.
class DataFormatter {
//put your code here
public function __construct() {
$documentRoot = filter_input(INPUT_SERVER, "DOCUMENT_ROOT");
include ($documentRoot . '/database/values/DataKeys.php');
}
public function cleanData($data){
if (is_null($data) || empty($data))
{
return;
}
foreach($data as $row){
$field1Value = $row[$keyField1];
unset($row[$keyField1]);
}
}
}
I also tried moving the include outside the class definition.
$documentRoot = filter_input(INPUT_SERVER, "DOCUMENT_ROOT");
include ($documentRoot . '/database/values/DataKeys.php');
The error that is being reported is :
Undefined variable: keyField1
SOULTION
Maybe not the optimal way but I took the include statement and placed it inside the function. The code above is just a demo of what I was trying to achieve not the actual code I am using.
the 2 variables are available just after the "include".
you can for example, put the 2 values in properties of the object
include ...;
$this->keyField1 = $keyField1;
$this->keyField2 = $keyField2;
You have to assign DataKeys.php to class member.
class DataFormatter {
private $keyField1;
private $keyField2;
public function __construct($filename) {
include $filename;
$this->keyField1 = $keyField1;
$this->keyField2 = $keyField2;
}
}
$dataFormatter = new DataFormatter(filter_input(INPUT_SERVER, 'DOCUMENT_ROOT') . '/database/values/DataKeys.php');
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Help me parse this file with PHP
I need to extract some text from a text file.suppose there is a text file in http://site.com/a.txt
And the contents of that file is like this:
var $name= 'name1';
var $age= 'age2';
var $phone= 'phonenumber';
var $a= 'asd';
var $district= 'district23';
How can I get the values of this text file (name1,age2,phonenumber,asd,district) in separate echo.
Use the file function to read the file into an array. Then loop through the array and each line in the file will be another element in the array. So make sure your file has line-breasks between the data.
Of course the best would be to have ready PHP code in a .php file which would then be included with the include function.
Organize the content of your text file like this : name1,age2,phonenumber,asd,district
And do this :
// Get the content of your file
$content = file_get_contents('a.text');
// Set your values with this
list($name, $age, $phone, $a, $district) = explode(',', $content);
// Then feel free to echo wathever you want
echo 'Name ' . $name;
Use an array and encode it: http://uk.php.net/manual/en/function.json-encode.php
I recommend using a class to encapsulate your data...
So imagine having a file called "person.php" that looks like this...
class Person
{
public $Name;
public $Age;
public $Phone;
public $A;
public $District;
}
You can then use the person class as a container.
include_once('person.php');
$person = new Person();
$person->Name = 'John Doe';
$person->Age = 52;
$person->Phone= '+441234 567 890';
$person->A = 'asd';
$person->District = 'District23';
Please note that "Age" is volatile (i.e. if the object lives for too long, the age will wrong!) You could avoid this by storing date of birth and then having a getAge() function on the Person object that gives you the correct age at any point in time.
The Person class is a plain PHP object, but you could add functions that add behaviour that relates to the concept of a Person, so the getAge() function would live on the Person class.
Finally, you could then store the object wherever you like using PHP's serialize and unserialize functions. The stored string that represents your object would look like this:
O:6:"Person":5:{
s:4:"Name";s:8:"John Doe";
s:3:"Age";i:52;
s:5:"Phone";s:15:"+441234 567 890";
s:1:"A";s:3:"asd";
s:8:"District";s:10:"District23";
}
And here is how you serialize the $person to look like this:
$serializedPerson = serialize($person);
echo $serializedPerson;
And converting from a string back to a Person is easy too:
$serializedPerson = 'O:6:"Person":5:{s:4:"Name";s:8:"John Doe";s:3:"Age";i:52;s:5:"Phone";s:15:"+441234 567 890";s:1:"A";s:3:"asd";s:8:"District";s:10:"District23";}';
$newPerson = unserialize($serializedPerson);
echo $newPerson->Name;
Summary
So if you stored you data in this serialized format, it is really easy to convert it directly into a PHP object that you can use without manually parsing the strings. You could store the string in a text file if you wanted - or a data store.
Rather than giving you the solution code I'm going to break this down into steps for you.
0) write the file in a machine readable format, e.g. name,age,phonenumber
1) Read from the file line by line
2) Break each line up according to the separator you used e.g. ","
3) Read in values into variables
4) Echo out
If you're stuck on something more specific, let us know.
For error logging I want to save an object as string in my database. I don't want to use serialization because that triggers the __sleep()-method. So is there another way to save an object as string without using serialize()?
class Foo {
public function __toString() {
return "Hooray";
}
}
echo new Foo;
Maybe even
echo var_export(new Foo, true);
You could to this:
ob_start();
var_dump($x);
ob_get_contents();
You could try this
$string = print_r($x, true);
To save $string in the databse you could compress the string:
$string = gzcompress($string);
To uncompress and print $string use:
echo '<pre>'.gzuncompress($string).'</pre>';
an other solution might be the json_encode-function (docu).
EDIT: the nice thing about it is, that you can easily parse it with nearly any programming language if you have to automatically analyse your log files ;-)
Hi I'm using Closure Compiler to compress and join a few JavaScript files the syntax is something like this;
$c = new PhpClosure();
$c->add("JavaScriptA.js")
->add("JavaScriptB.js")
->write();
How could I make it systematically add more files from an array lets say for each array element in $file = array('JavaScriptA.js','JavaScriptB.js','JavaScriptC.js',..) it would execute the following code
$c = new PhpClosure();
$c->add("JavaScriptA.js")
->add("JavaScriptB.js")
->add("JavaScriptC.js")
->add
...
->write();
Thank you so much in advance!
The PhpClosure code uses method chaining to reduce repeated code and make everything look slightly nicer. The functions (or at least the add function) returns $this (The object the function was called on).
The code in the first sample could be written as:
$c = new PhpClosure();
$c->add("JavaScriptA.js");
$c->add("JavaScriptB.js");
$c->write();
The middle section (The add function calls) can then be transformed so that it loops over an array of files rather than having to add a line for each file.
$files = array("JavaScriptA.js", "JavaScriptB.js");
$c = new PhpClosure();
foreach ( $files as $file ){
$c->add($file);
}
$c->write();
This doesn't work:
test.php:
include_once('test-include.php');
$main = new mainClass();
//======================================================================
class mainClass {
function __construct() {
$test2 = new Test2();
echo $test2->var;
}
}
//======================================================================
class Test2 extends Test1 { // test2
var $var = 'b';
}
test-include.php:
// this does get printed out, so I know the include statement is working
echo 'DEBUG: this is the test-include.php file<br>';
//======================================================================
class Test1 { // test1
var $var = 'a';
}
It gives the following error
PHP Fatal error: Class 'Test2' not found in /path/to/test.php on line 8
whereas this does work
test2.php:
// this is in the same position as the include statement in test.php
//======================================================================
class Test1 { // test1
var $var = 'a';
}
$main = new mainClass();
//======================================================================
class mainClass {
function __construct() {
$test2 = new Test2();
echo $test2->var;
}
}
//======================================================================
class Test2 extends Test1 { // test2
var $var = 'b';
}
Why does putting the Base class (Test1) in an include file cause the child class that is extending it to not be found? In other words, the first example is failing because it can't find Test2 when we attempt to instantiate it. This kind of makes sense as we haven't gotten to Test2 in the code execution flow yet. However, in the second example (without the include statement) there's no error, even though it's a similar situation (we haven't reached the Test2 class in code execution yet)
Oh, and this is under version 5.1.6.
UPDATE:
OK, Daff is correct - if I move
$main = new mainClass();
to the end in the test.php example, it works. I would still like to know why it doesn't work if the above line isn't at the end - it works just fine in the test2.php example which doesn't have the $main = new mainClass() line at the end.
UPDATE 2:
OK, I've tried using require, require_once and include in place of include_once - none of these work. And I also added a test echo statement to the test-include.php file and it gets printed out (plus I don't get an error about a non-existent include file) so I know the include statement is working.
This should have something to do with the definition order and that EVERY class should be included before you actually work with them. If you put the call of
$main = new mainClass();
At the end of your script it works fine even with the include file because all the classes are defined already. Eventually you should have a look at the PHP autoload function because you will get rid of these problem with one small function.
OK, I think I may have figured this one out. According to this bug report:
http://bugs.php.net/bug.php?id=30453
PHP 4 allowed classes to be defined after they are used but for PHP 5, in the words of the end poster on the bug thread:
PHP5 supports it [declaring classes
after they are used] for backward
compatibility, but we don't plan
support for all combinations.
So I'm guessing this particular case is one of those unsupported combinations.