[ Index ] |
PHP Cross Reference of phool |
[Summary view] [Print] [Text view]
1 <?php 2 //============================================================================ 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Lesser General Public License (LGPL) as 5 // published by the Free Software Foundation, either version 3 of the License, 6 // or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Lesser General Public License for more details. 12 // 13 // You should have received a copy of the GNU Lesser General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 //============================================================================ 16 //============================================================================= 17 /** 18 * @copyright Francois Laupretre <phool@tekwire.net> 19 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, V 2.0 20 * @category phool 21 * @package phool 22 */ 23 //============================================================================ 24 25 namespace Phool; 26 27 //============================================================================ 28 /** 29 * This abstract class implements an object which can be saved and retrieved 30 * to/from a file on disk. 31 * 32 * It exposes the {@link load()} and {@link save()} methods. 33 * 34 * It also provides a checksum mechanism transparent to the descendant 35 * class. Everytime an object is read from storage, its checksum is computed 36 * and compared to the value that was stored at save() time. 37 * 38 * The descendant class must define two methods named serialize and 39 * unserialize to transmit/retrieve the data to save. 40 * 41 * Note: Late static binding would allow to access the descendant class 42 * properties and get the magic string from the toplevel class at runtime. 43 * Unfortunately, it is implemented in versions of PHP >= 5.3, which is too 44 * restrictive. So, we use another way. 45 */ 46 47 //---------------------------------------------------------------------------- 48 49 abstract class Persistent extends Modifiable 50 { 51 // @var string The magic string to write and check 52 53 private $magic; 54 55 // @var string The last loaded path. Allows to call save() without argument. 56 57 private $path=null; 58 59 //---------------------------------------------------------------------------- 60 /** 61 * Return the properties to save as a string 62 * 63 * @return string 64 */ 65 66 abstract protected function serialize(); 67 68 //---------------------------------------------------------------------------- 69 /** 70 * Restore data from the result of a previous {@link __serialize()} execution 71 * 72 * @param mixed $data The data returned by a previous {@link __serialize()} 73 * execution 74 * 75 * @return void 76 */ 77 78 abstract protected function unserialize($data); 79 80 //---------------------------------------------------------------------------- 81 /** 82 * Class constructor 83 * 84 * @param string $magic The magic string to use when writing/reading a file 85 * @param string|null $path A file to load if not null 86 * @return void 87 */ 88 89 protected function __construct($magic,$path=null) 90 { 91 $this->magic=$magic; 92 parent::__construct(); 93 if (!is_null($path)) $this->load($path); 94 } 95 96 //---------------------------------------------------------------------------- 97 /** 98 * Records a path 99 * 100 * @param string $path 101 * @return void 102 */ 103 104 public function setPath($path) 105 { 106 $this->path=$path; 107 } 108 109 //---------------------------------------------------------------------------- 110 /** 111 * Restore data from a save()d file 112 * 113 * @param string $path Path of the file to load 114 * @return void 115 * @throws Exception if file cannot be loaded 116 */ 117 118 public function load($path) 119 { 120 if (!file_exists($path)) throw new \Exception("$path: File does not exist"); 121 122 try 123 { 124 $buf=file_get_contents($path); 125 if ($buf===false) throw new \Exception("$path: Cannot get file contents"); 126 //-- Check magic 127 if (substr($buf,0,strlen($this->magic))!==$this->magic) 128 throw new \Exception("Bad magic string"); 129 //-- Skip magic string 130 $buf=substr($buf,strlen($this->magic)); 131 //-- Unserialize toplevel array 132 $a=unserialize($buf); 133 if ((!is_array($a)) 134 ||(!array_key_exists('crc',$a)) 135 ||(!array_key_exists('data',$a))) 136 throw new \Exception('Invalid format'); 137 138 $data=$a['data']; 139 if (crc32($data) !== $a['crc']) 140 throw new \Exception('Wrong checksum'); 141 142 $this->unserialize($data); 143 } 144 catch (\Exception $e) 145 { 146 throw new \Exception("$path: Cannot load file: ".$e->getMessage()); 147 } 148 149 $this->setPath($path); 150 } 151 152 //---------------------------------------------------------------------------- 153 /** 154 * Save data to a file on disk 155 * 156 * @param string|null $path Path to save or null if same as load() 157 * @return void 158 * @throws Exception if write failed or path cannot be determined 159 */ 160 161 public function save($path=null) 162 { 163 if (is_null($path)) 164 { 165 if (is_null($this->path)) 166 throw new \Exception('Save path cannot be determined'); 167 $path=$this->path; 168 } 169 170 $value=$this->serialize(); // Call toplevel method 171 $data=serialize(array( 172 'crc' => crc32($value), 173 'data' => $value 174 )); 175 176 if (file_put_contents($path,$this->magic.$data)===false) 177 throw new \Exception("$path: Cannot write file"); 178 179 //-- Write is OK. Now we can clear the 'modified' flag 180 181 parent::clearModified(); 182 } 183 184 //---------------------------------------------------------------------------- 185 /** 186 * Save object to a file if it was modified since last load() or save() 187 * 188 * @param string|null $path Path to save or null if same as load() 189 * @return void 190 * @throws Exception if write failed 191 */ 192 193 public function saveIfModified($path=null) 194 { 195 if ($this->modified()) $this->save($path); 196 } 197 198 } // End of class 199 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jun 4 19:17:11 2015 | Cross-referenced by PHPXref 0.7.1 |