PHP class public variables undefined after deserialization

So, at some point, the ajax call sends JSON, which I convert to objects and save in the session:

if ( $deps = json_decode( $raw_json, true ) ) { $pkgs = array(); foreach ( $deps['vector'] as $key ) { if ( strcasecmp( $key['package'], $key['component'] ) == 0 ) { $package = new Package(); $package->name = $key['package']; $package->version = $key['version']; $package->cxx_include = $key['cxx_inc']; $package->cxx_link = $key['cxx_link']; $pkgs[] = $package; } else { foreach( $pkgs as $package ) { if ( $package->name == $key['package'] ) { $component = new Component(); $component->name = $key['component']; $component->cxx_link = $key['cxx_link']; $package->components[] = $component; } } } } $_SESSION['pkgs'] = serialize( $pkgs ); 

The actual classes are simply:

 class Component { public $name; public $cxx_link; } class Package { public $name; public $version; public $cxx_inclue; public $cxx_link; public $components = array(); } 

When at some later point I deserialise and try to analyze them:

  $pkgs = isset( $_SESSION['pkgs'] ) ? unserialize($_SESSION['pkgs']) : array(); foreach ( $pkgs as $package ) { fwrite( $cmake, "find_package(" . $package->name . " " . $package->version . " " ); if ( count( $package->components ) > 0 ) { fwrite( $cmake, "COMPONENTS " ); foreach ( $package->components as $component ) fwrite( $cmake, $component->name. " " ); fwrite( $cmake, "REQUIRED )\r\n" ); } if ( isset( $package->cxx_include ) ) // ERROR here: undefined variable fwrite( $cmake, "include_directories(${".$package->cxx_include."})\r\n" ); if ( isset( $package->cxx_link ) ) // ERROR here: undefined variable fwrite( $cmake, "target_link_libraries($rapp_name ${".$package->cxx_link."})\r\n" ); foreach ( $package->components as $component ) { if ( isset($component->cxx_link) ) // ERROR here: undefined variable fwrite( $cmake, "target_link_libraries($rapp_name ${".$component->cxx_link."})\r\n" ); } } 

What really puzzles me does NOT mean that the undefined variable is $ component-> cxx_link or $ package-> cxx_link, but what I will show is the actual value from JSON.

For example, if JSON:

 { "vector": [ { "package": "Boost", "version": "1.54", "component": "Boost", "cxx_inc": "Boost_INCLUDE_DIRS", "cxx_link": "Boost_LIBRARIES" }, { "package": "Boost", "version": "1.54", "component": "date_time", "cxx_inc": "", "cxx_link": "Boost_DATE_TIME_LIBRARY" }, { "package": "Boost", "version": "1.54", "component": "filesystem", "cxx_inc": "", "cxx_link": "Boost_FILESYSTEM_LIBRARY" }, { "package": "Opencv", "version": "3.0", "component": "OpenCV", "cxx_inc": "OpenCV_INCLUDE_DIRS", "cxx_link": "OpenCV_LIBS" }, { "package": "Eigen3", "version": "3.0", "component": "Eigen3", "cxx_inc": "EIGEN3_INCLUDE_DIR", "cxx_link": "" } ] } 

I get as errors:

 PHP Notice: Undefined variable: .Boost_INCLUDE_DIRS. PHP Notice: Undefined variable: .Boost_LIBRARIES. PHP Notice: Undefined variable: .OpenCV_INCLUDE_DIRS. 

What are the values ​​for which I set the class members. If I understand this correctly, does the assignment operation during the JSON iteration make some kind of small copy?

EDIT According to Barmar's comments, I removed serialize / unserialize and moved the class definition to the top of every file that uses these classes. I no longer get a startup error, but I still get exactly the same undefined variable.

+6
source share
1 answer

Fixed:

So the problem is that you are using double quotes, not single quotes as strings. PHP has a variable of variables, and you use it unintentionally (see http://php.net/manual/en/language.variables.variable.php ).

Switch each line containing something like "${something}" into single quotes (or avoid the dollar sign, as Alex said), and everything will be fine, i.e.:

fwrite( $cmake, "include_directories(${".$package->cxx_include."})\r\n" );

will be

fwrite( $cmake, 'include_directories(${'.$package->cxx_include.'})'."\r\n" );

(Note that you cannot use \r or \n in single quote strings.)

Old answer:

You have a typo in the Package class.

You assign it to $package->cxx_include , but the "d" is missing in the actual name.

 class Package { public $name; public $version; public $cxx_inclue; // typo public $cxx_link; public $components = array(); } 
+4
source

Source: https://habr.com/ru/post/987466/


All Articles