【问题标题】:Strange Behavior Serializing Objects and Caching Them序列化对象并缓存它们的奇怪行为
【发布时间】:2012-04-05 18:18:26
【问题描述】:

我遇到了一个似乎无法缩小范围的问题。在 Zend Framework 应用程序中,我使用 Zend Cache 来缓存自定义 Response 对象中包含的潮汐和天气数据。最初创建数据时,一切正常。我序列化它并缓存它。然后当我点击刷新并从缓存中提取数据时,我收到以下错误:

消息:字符串无法解析为 XML

堆栈跟踪:

0 /home/cillosis/mysites/tidely/application/views/scripts/tides/location.phtml(38):SimpleXMLElement->__construct('')

1 /home/cillosis/mysites/tidely/library/Zend/View.php(108): include('/home/cillosis/...')

2 /home/cillosis/mysites/tidely/library/Zend/View/Abstract.php(888): Zend_View->_run('/home/cillosis/...')

...

这发生在我访问自定义“响应对象”中包含的 XML 的视图中:

<div class="data-box">

<h3>Current Weather</h3>
<hr>
<?php

// *** THIS IS LINE 38  ***                         
$weather_XML = new SimpleXMLElement($this->response->_weatherdata->weatherResults);
$params = $weather_XML->data->parameters;

$img_path = $params->{'conditions-icon'}->{'icon-link'};

echo("<img src='".$img_path."'>");

...

这是第一次运行时(缓存之前)对象相关部分的转储:

["_weatherdata"]=>
  object(Tidely_WeatherData)#79 (6) {
    ["weatherResults"]=>
    string(6399) "<?xml version="1.0"?>
       <dwml version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:noNamespaceSchemaLocation="http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd">
          ...
       </dwml> "

在您看到“...”的地方有很多其他 XML 数据。 XML 来自 NWS(国家气象服务)API,我通过 XML 验证器运行它,它没有显示任何错误。一旦我序列化我的对象并缓存它,问题就会发生。下面是我的 Zend 缓存设置:

// Setup caching
$frontendOptions = array('lifeTime' => 30, 'automatic_seralization' => false);
$backendOptions = array('cache_dir' => '../application/cache');
$this->_cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);

我正在用这个进行缓存和检索:

// Assign cache id
// Example query: "Chesapeake Bay Virginia"
$cache_id = 'request_results_' . $this->response->_querydata->query);
$cache_id = str_replace(' ', '_', $cache_id);
$cache_id = str_replace('-', '_', $cache_id);

// Check cache for this query
if ( ($results = $this->_cache->load($cache_id)) === false)
{
   // Cache not found, process request and generate response
   ...

   // Cache request output for specific query
   $serialized_data = serialize($this->response);
   $this->_cache->save($serialized_data, $cache_id);

   // Return processed request results
   return $this->response;
}
else
{
   // Return results from cache
   return unserialize($results);
}

一旦我发出请求并缓存它,$this-&gt;response 对象输出如下:

object(Tidely_ResponseData)#65 (7) { ["_querydata"]=> object(Tidely_QueryData)#66 (9) { ["query"]=> string(40) "bayou-la-batre-mississippi- sound alabama" ["source"]=> string(15) "TidesController" ["request_type"]=> string(3) "url" ["url_components"]=> array(2) { ["state"]=>字符串(7)“阿拉巴马州”[“位置”]=> 字符串(32)“bayou-la-batre-mississippi-sound”} [“return_type”]=> 字符串(4)“JSON”[“time_range”]= > array(2) { ["start"]=> object(DateTime)#64 (3) { ["date"]=> string(19) "2012-04-05 18:06:51" ["timezone_type" ]=> int(3) ["timezone"]=> string(3) "UTC" } ["end"]=> object(DateTime)#63 (3) { ["date"]=> string(19) "2012-04-06 18:06:51" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" } } ["hasError"]=> bool(false) ["userMessage"]=> NULL ["logMessage"]=> NULL } ["_locationdata"]=> object(Tidely_LocationData)#80 (31) { ["location_id"]=> string(5) "18921" [" station_name"]=> string(33) "Bayou La Batre, Mississippi Sound" ["station_url_name"]=> string(32) "bayou-la-batre-mississi ppi-sound" ["station_type"]=> string(11) "下属" ["station_id"]=> string(7) "8739051" ["station_lat"]=> string(8) "+30.3717" ["station_lon "]=> 字符串(8) "-88.2750" ["station_height_offset_high"]=> 字符串(5) "*1.23" ["station_height_offset_low"]=> 字符串(5) "*1.23" ["station_time_offset_high"]=> 字符串(3) "112" ["station_time_offset_low"]=> 字符串(2) "74" ["station_ref_station_id"]=> 字符串(7) "8760551" ["state_id"]=> 字符串(1) "1" [" state_name"]=> string(7) "Alabama" ["state_url_name"]=> string(7) "alabama" ["timezone"]=> string(2) "-6" ["dst"]=> string( 1) "1" ["city_name"]=> string(14) "Bayou La Batre" ["city_zip"]=> string(5) "36509" ["city_lat"]=> string(7) "30.4014" [ "city_lon"]=> string(8) "-88.2467" ["adjacentStations"]=> string(321) "a:10:{i:8739051;d:2.6562027890531361;s:7:"TEC4393";d:8.0529290086617618 ; I:8740448; d:11.564338218805837; I:8735180; d:14.637787569358004; I:8741196; d:17.602722038773138; I:8734635; d:17.824002491920826; I:8733810; d:19.474837234444919; I:8737048; d:24.4 14028460259932;i:8742221;d:27.466706516499691;i:8731952;d:31.251405048051701;}" ["city_distance"]=> string(15) "2.6562027890531" ["multipleResults"]=> string(0) "" "]=> int(0) ["hasMultiple"]=> bool(false) ["showStates"]=> bool(false) ["showLocations"]=> bool(false) ["hasError"]=> bool( false) ["userMessage"]=> NULL ["logMessage"]=> NULL } ["_tidedata"]=> object(Tidely_TideData)#68 (6) { ["tideResults"]=> NULL ["queryStart"]= > NULL ["queryEnd"]=> NULL ["hasError"]=> bool(false) ["userMessage"]=> NULL ["logMessage"]=> NULL } ["_weatherdata"]=> object(Tidely_WeatherData)# 79 (6) { ["weatherResults"]=> string(6399) " 气象预报 2012-04-05T18:06:57Z http://graphical.weather.gov/xml/ 气象发展实验室产品生成科http://www.nws.noaa.gov/disclaimer.html http://www.weather.gov/ @ 987654323@ http://www.weather.gov/feedback.php point1 http://forecast.weather.gov/MapClick.php?textField1=30.37&textField2=-88.28 k-p24h-n1-1 2012-04-05T08:00:00-05:00 2012-04-05T20:00:00-05 :00 k-p24h-n1-2 2012-04-05T20:00:00-05:00 2012-04-06T09:00:00-05:00 k-p3h-n5-3 201 2-04-05T13:00:00-05:00 2012-04-05T16:00:00-05:00 2012-04-05T19:00:00-05:00 2012-04-05T22:00:00-05 :00 2012-04-06T01:00:00-05:00 每日最高温度 81 每日最低温度 63 温度 79 79 74 69 67 露点温度 66 65 64 64 61 风速 12 11 11 13 14 风向 240 260 280 300 330 相对湿度 64 63 71 84 81 天气类型、覆盖范围和强度条件图标 http://forecast.weather.gov/images/wtf/tsra60.jpg http://forecast.weather.gov/images/wtf/tsra60.jpg http://forecast.weather.gov/images/wtf/scttsra60.jpg http://forecast.weather.gov/ images/wtf/nscttsra20.jpg http://forecast.weather.gov/images/wtf/nsct.jpg " ["queryStart"]=> float(1333649211.6989) ["queryEnd"]=> float(1333649217.2038) ["hasError"]=> bool(false) ["userMessage"]= > NULL ["logMessage"]=> NULL } ["hasError"]=> bool(false) ["userMessage"]=> NULL ["logMessage"]=> NULL }

当我查看源代码时,“weatherResults”部分有 XML,我没有复制和粘贴它,因为它相当长。这是当我按下刷新并使用上述对象的缓存副本时发生的情况:

object(Tidely_ResponseData)#65 (7) { ["_querydata"]=> object(Tidely_QueryData)#66 (9) { ["query"]=> string(40) "bayou-la-batre-mississippi- sound alabama" ["source"]=> string(15) "TidesController" ["request_type"]=> string(3) "url" ["url_components"]=> array(2) { ["state"]=>字符串(7)“阿拉巴马州”[“位置”]=> 字符串(32)“bayou-la-batre-mississippi-sound”} [“return_type”]=> 字符串(4)“JSON”[“time_range”]= > array(2) { ["start"]=> object(DateTime)#64 (3) { ["date"]=> string(19) "2012-04-05 18:10:30" ["timezone_type" ]=> int(3) ["timezone"]=> string(3) "UTC" } ["end"]=> object(DateTime)#63 (3) { ["date"]=> string(19) "2012-04-06 18:10:30" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" } } ["hasError"]=> bool(false) ["userMessage"]=> NULL ["logMessage"]=> NULL } ["_locationdata"]=> object(Tidely_LocationData)#67 (31) { ["location_id"]=> string(0) "" ["station_name "]=> string(0) "" ["station_url_name"]=> string(0) "" ["station_type"]=> string(0) "" ["station_id"]=> string(0) "" ["station_lat"]=> string(0) "" ["station_lon"]=> string(0) "" ["station_height_offset_high"]=> string(0) "" ["station_height_offset_low"]=> string(0) "" ["station_time_offset_high"]=> string(0) "" ["station_time_offset_low"]=> string(0) "" ["station_ref_station_id"]=> string(0) "" ["state_id"]=> string( 0) "" ["state_name"]=> string(0) "" ["state_url_name"]=> string(0) "" ["timezone"]=> string(0) "" ["dst"]=> string(0) "" ["city_name"]=> string(0) "" ["city_zip"]=> string(0) "" ["city_lat"]=> string(0) "" ["city_lon"] => string(0) "" ["adjacentStations"]=> string(0) "" ["city_distance"]=> string(0) "" ["multipleResults"]=> string(0) "" ["multipleCount "]=> int(0) ["hasMultiple"]=> bool(false) ["showStates"]=> bool(false) ["showLocations"]=> bool(false) ["hasError"]=> bool( false) ["userMessage"]=> NULL ["logMessage"]=> NULL } ["_tidedata"]=> object(Tidely_TideData)#68 (6) { ["tideResults"]=> NULL ["queryStart"]= > NULL ["queryEnd"]=> NULL ["hasError"]=> bool(false) ["userMessage"]=> NULL [ "logMessage"]=> NULL } ["_weatherdata"]=> object(Tidely_WeatherData)#69 (6) { ["weatherResults"]=> NULL ["queryStart"]=> NULL ["queryEnd"]=> NULL [ "hasError"]=> bool(false) ["userMessage"]=> NULL ["logMessage"]=> NULL } ["hasError"]=> bool(false) ["userMessage"]=> NULL ["logMessage" ]=> 空 }

在序列化/反序列化和保存缓存的过程中,它以某种方式将所有字符串设置为空或NULL!所以当然,我收到了 XML 错误,因为它是空的。

还有其他人在使用 Zend Cache(或任何其他缓存库)缓存对象时遇到问题吗?这与序列化有关吗?我缺少缓存设置吗?很抱歉解释太长,提前感谢您的帮助!

【问题讨论】:

    标签: php zend-framework serialization zend-cache


    【解决方案1】:

    PHP 资源不能序列化,这就是为什么你不能序列化你的对象(这将间接序列化一个 SimpleXML 对象)。

    在序列化之前,您需要将您的对象转换为格式正确的 XML 字符串 (SimpleXMLElement::asXML()),并且在您的对象被反序列化后,将您的字符串重新转换为 SimpleXML 对象 (simplexml_load_string())。

    See here 了解更多信息。 This question 也很有用。


    编辑新的细节:在您的问题中有这些新元素,我知道您的问题不是来自序列化的 SimpleXML 对象。你有什么理由不使用automatic_serialization? (顺便说一下,“i”,我猜你拼错了)而不是让 Zend_Cache 自动序列化/反序列化你的对象。


    编辑#2:从 cillosis 中阅读下面的 cmets 以获得最终解决方案。

    【讨论】:

    • XML 不是 SimpleXML 对象。它是从 API 调用返回的字符串,您可以从中看到:["weatherResults"]=&gt; string(6399) "..."。我知道您不能序列化 PHP 资源,这是一个标准对象,并且可以很好地序列化而不会引发错误。还有其他想法吗?
    • 好吧,我只是在读你的堆栈跟踪,也许我错了,但似乎你正试图在那儿反序列化一个 SimpleXML 对象:0 /home/cillosis/mysites/tidely/application/views/scripts/tides/location.phtml(38): SimpleXMLElement-&gt;__construct('')。你的调试器说什么?第 38 行是什么?
    • 不,我不是。请参阅上面的编辑,其中我从字符串值$this-&gt;response-&gt;_weatherdata-&gt;weatherResults 创建了一个 SimpleXML 对象。反序列化发生在我进行缓存的上面那段代码中。在序列化/反序列化的某个时刻,它正在重置对象(因为没有更好的词)。这是我第一次在 PHP 中缓存时遇到这个问题。
    • 我不敢相信我没有注意到拼写错误。奇怪的是 Zend Cache 就这样接受了它而没有抛出任何类型的错误。无论如何,我尝试让它进行序列化,但仍然遇到同样的问题。我的对象仍然反序列化为空。我注意到的另一件有趣的事情是查看缓存文件,所有数据都在那里。所以它在反序列化时丢失。很奇怪。
    • 我解决了。与序列化无关。结果当我做$response = $requestHandler-&gt;response; 时,它返回了一个空的 Tidely_ResponseData 对象,即使它在类中被定义为 public。最终只是从执行$response = $requestHander-&gt;processRequest(); 中获取了返回值。感谢您的所有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多