gestion des fichiers de cache
This commit is contained in:
		
							parent
							
								
									c80d99e829
								
							
						
					
					
						commit
						3ea51e70b4
					
				
							
								
								
									
										4
									
								
								src/file/cache/CacheData.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								src/file/cache/CacheData.php
									
									
									
									
										vendored
									
									
								
							| @ -12,8 +12,8 @@ class CacheData { | ||||
|   /** @var callable une fonction permettant de calculer la donnée */ | ||||
|   const COMPUTE = null; | ||||
| 
 | ||||
|   function __construct(?string $name=null, $compute=null) { | ||||
|     $this->name = $name ?? static::NAME ?? bin2hex(random_bytes(8)); | ||||
|   function __construct($compute=null, ?string $name=null) { | ||||
|     $this->name = $name ?? static::NAME ?? ""; | ||||
|     $this->compute = func::withn($compute ?? static::COMPUTE); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										334
									
								
								src/file/cache/CacheFile.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										334
									
								
								src/file/cache/CacheFile.php
									
									
									
									
										vendored
									
									
								
							| @ -2,29 +2,65 @@ | ||||
| namespace nulib\file\cache; | ||||
| 
 | ||||
| use Exception; | ||||
| use nulib\cl; | ||||
| use nulib\cv; | ||||
| use nulib\file; | ||||
| use nulib\file\SharedFile; | ||||
| use nulib\os\path; | ||||
| use nulib\php\time\DateTime; | ||||
| use nulib\php\time\Delay; | ||||
| use nulib\str; | ||||
| use nulib\ValueException; | ||||
| 
 | ||||
| class CacheFile extends SharedFile { | ||||
|   /** @var string|int durée de vie par défaut des données mises en cache  */ | ||||
|   const DURATION = "1D"; // jusqu'au lendemain
 | ||||
| 
 | ||||
|   const EXT = ".cache"; | ||||
| 
 | ||||
|   function __construct($file, ?array $params=null) { | ||||
|     if ($file === null) { | ||||
|       $rand = bin2hex(random_bytes(8)); | ||||
|       $file = sys_get_temp_dir()."/$rand"; | ||||
|     } | ||||
|     $file = path::ensure_ext($file, ".metadata.cache", ".cache"); | ||||
|     $file = path::ensure_ext($file, self::EXT); | ||||
|     $this->basedir = path::dirname($file); | ||||
|     $basename = path::filename($file); | ||||
|     $this->basename = str::without_suffix(path::ext($basename), $basename); | ||||
|     $this->duration = Delay::with($params["duration"] ?? static::DURATION); | ||||
|     $this->basename = str::without_suffix(self::EXT, $basename); | ||||
|     $this->initialDuration = Delay::with($params["duration"] ?? static::DURATION); | ||||
|     $this->overrideDuration = $params["override_duration"] ?? false; | ||||
|     $this->readonly = $params["readonly"] ?? false; | ||||
|     $this->cacheNull = $params["cache_null"] ?? false; | ||||
|     $data = $params["data"] ?? null; | ||||
|     if ($data === null) { | ||||
|       $this->dataDefs = null; | ||||
|       $this->data = null; | ||||
|     } elseif ($data instanceof CacheData) { | ||||
|       $this->dataDefs = null; | ||||
|       $this->data = $data; | ||||
|     } elseif (!is_array($data)) { | ||||
|       $this->dataDefs = null; | ||||
|       $this->data = $this->getData($data); | ||||
|     } else { | ||||
|       $dataDefs = []; | ||||
|       $tmpdefs = $data; | ||||
|       $index = 0; | ||||
|       foreach ($tmpdefs as $key => $data) { | ||||
|         $odef = $data; | ||||
|         if ($data instanceof CacheData) { | ||||
|         } elseif (cv::subclass_of($data, CacheData::class)) { | ||||
|           $data = new $data(); | ||||
|         } else { | ||||
|           throw ValueException::invalid_type($odef, CacheData::class); | ||||
|         } | ||||
|         if ($key === $index) { | ||||
|           $index++; | ||||
|           $key = $data->getName(); | ||||
|         } | ||||
|         $dataDefs[$key] = $data; | ||||
|       } | ||||
|       $this->dataDefs = $dataDefs; | ||||
|     } | ||||
|     parent::__construct($file); | ||||
|   } | ||||
| 
 | ||||
| @ -34,12 +70,33 @@ class CacheFile extends SharedFile { | ||||
|   /** @var string nom de base des fichiers de cache */ | ||||
|   protected string $basename; | ||||
| 
 | ||||
|   protected Delay $duration; | ||||
|   protected Delay $initialDuration; | ||||
| 
 | ||||
|   protected bool $overrideDuration; | ||||
| 
 | ||||
|   protected bool $readonly; | ||||
| 
 | ||||
|   protected bool $cacheNull; | ||||
| 
 | ||||
|   protected ?array $dataDefs; | ||||
| 
 | ||||
|   protected ?CacheData $data; | ||||
| 
 | ||||
|   protected function getData($data): CacheData { | ||||
|     if ($data === null) { | ||||
|       return $this->data ??= new CacheData(function() { | ||||
|         return $this->compute(); | ||||
|       }); | ||||
|     } | ||||
|     $odata = $data; | ||||
|     if (is_string($data) || is_int($data)) { | ||||
|       $data = $this->dataDefs[$data] ?? null; | ||||
|       if ($data === null) throw ValueException::invalid_key($odata); | ||||
|     } | ||||
|     if ($data instanceof CacheData) return $data; | ||||
|     throw ValueException::invalid_type($odata, CacheData::class); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * vérifier si le fichier est valide. s'il est invalide, il faut le recréer. | ||||
|    * | ||||
| @ -50,31 +107,42 @@ class CacheFile extends SharedFile { | ||||
|     return $this->getSize() > 0; | ||||
|   } | ||||
| 
 | ||||
|   protected ?DateTime $start; | ||||
| 
 | ||||
|   protected ?Delay $duration; | ||||
| 
 | ||||
|   protected ?array $datafilenames; | ||||
| 
 | ||||
|   /** charger les données. le fichier a déjà été verrouillé en lecture */ | ||||
|   protected function loadMetadata(): ?array { | ||||
|     $this->rewind(); | ||||
|     [ | ||||
|       "start" => $start, | ||||
|       "duration" => $duration, | ||||
|       "datafiles" => $datafiles, | ||||
|     ] = $this->unserialize(null, false, true); | ||||
|     if ($this->overrideDuration) { | ||||
|       $duration = Delay::with($this->duration, $start); | ||||
|   protected function loadMetadata(): void { | ||||
|     if ($this->isValid()) { | ||||
|       $this->rewind(); | ||||
|       [ | ||||
|         "start" => $start, | ||||
|         "duration" => $duration, | ||||
|         "datafiles" => $datafilenames, | ||||
|       ] = $this->unserialize(null, false, true); | ||||
|       if ($this->overrideDuration) { | ||||
|         $duration = Delay::with($this->initialDuration, $start); | ||||
|       } | ||||
|       $datafilenames = array_fill_keys($datafilenames, true); | ||||
|     } else { | ||||
|       $start = null; | ||||
|       $duration = null; | ||||
|       $datafilenames = []; | ||||
|     } | ||||
|     return [ | ||||
|       "start" => $start, | ||||
|       "duration" => $duration, | ||||
|       "datafiles" => $datafiles, | ||||
|     ]; | ||||
|     $this->start = $start; | ||||
|     $this->duration = $duration; | ||||
|     $this->datafilenames = $datafilenames; | ||||
|   } | ||||
| 
 | ||||
|   /** tester s'il faut mettre les données à jour. le fichier a déjà été verrouillé en lecture */ | ||||
|   /** | ||||
|    * tester s'il faut mettre les données à jour. le fichier a déjà été | ||||
|    * verrouillé en lecture | ||||
|    */ | ||||
|   protected function shouldUpdate(bool $noCache=false): bool { | ||||
|     if ($this->isValid()) { | ||||
|       /** @var Delay $duration */ | ||||
|       ["duration" => $duration, | ||||
|       ] = $this->loadMetadata(); | ||||
|       $expired = $duration->isElapsed(); | ||||
|       $expired = $this->duration->isElapsed(); | ||||
|     } else { | ||||
|       $expired = false; | ||||
|       $noCache = true; | ||||
| @ -83,49 +151,39 @@ class CacheFile extends SharedFile { | ||||
|   } | ||||
| 
 | ||||
|   /** sauvegarder les données. le fichier a déjà été verrouillé en écriture */ | ||||
|   protected function saveMetadata(?DateTime $start, ?Delay $duration, array $datafiles): void { | ||||
|     $duration ??= $this->duration; | ||||
|     if ($start === null) { | ||||
|       $start = new DateTime(); | ||||
|       $duration = Delay::with($duration, $start); | ||||
|   protected function saveMetadata(): void { | ||||
|     $this->duration ??= $this->initialDuration; | ||||
|     if ($this->start === null) { | ||||
|       $this->start = new DateTime(); | ||||
|       $this->duration = Delay::with($this->duration, $this->start); | ||||
|     } | ||||
|     $datafilenames = array_keys($this->datafilenames); | ||||
|     $this->ftruncate(); | ||||
|     $this->serialize([ | ||||
|       "start" => $start, | ||||
|       "duration" => $duration, | ||||
|       "datafiles" => $datafiles, | ||||
|       "start" => $this->start, | ||||
|       "duration" => $this->duration, | ||||
|       "datafiles" => $datafilenames, | ||||
|     ], false, true); | ||||
|   } | ||||
| 
 | ||||
|   function loadData(string $datafile) { | ||||
|     $datafile = path::join($this->basedir, $datafile); | ||||
|   protected function loadData(string $datafile) { | ||||
|     return file::reader($datafile)->unserialize(); | ||||
|   } | ||||
| 
 | ||||
|   function saveData(string $datafile, $data): void { | ||||
|     $datafile = path::join($this->basedir, $datafile); | ||||
|   protected function saveData(string $datafile, $data): void { | ||||
|     file::writer($datafile)->serialize($data); | ||||
|   } | ||||
| 
 | ||||
|   protected function unlinkDatafile(string $datafile): void { | ||||
|     @unlink(path::join($this->basedir, $datafile)); | ||||
|   protected function unlinkDatafile(string $datafilename): void { | ||||
|     $datafile = path::join($this->basedir, $datafilename); | ||||
|     @unlink($datafile); | ||||
|     unset($this->datafilenames[$datafilename]); | ||||
|   } | ||||
| 
 | ||||
|   protected function unlinkFiles(?array $datafiles): void { | ||||
|     if ($datafiles === null && $this->isValid()) { | ||||
|       $this->lockRead(); | ||||
|       try { | ||||
|         ["datafiles" => $datafiles | ||||
|         ] = $this->loadMetadata(); | ||||
|       } finally { | ||||
|         $this->unlock(); | ||||
|       } | ||||
|     } | ||||
|     @unlink($this->file); | ||||
|     if ($datafiles !== null) { | ||||
|       foreach ($datafiles as $datafile) { | ||||
|         $this->unlinkDatafile($datafile); | ||||
|       } | ||||
|   protected function unlinkFiles(bool $datafilesOnly=false): void { | ||||
|     if (!$datafilesOnly) @unlink($this->file); | ||||
|     foreach ($this->datafilenames as $datafilename) { | ||||
|       $this->unlinkDatafile($datafilename); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| @ -134,101 +192,157 @@ class CacheFile extends SharedFile { | ||||
|     return $this->cacheNull || $value !== null; | ||||
|   } | ||||
| 
 | ||||
|   function get(?CacheData $data=null, bool $noCache=false) { | ||||
|     $this->lockRead(); | ||||
|   protected ?DateTime $ostart; | ||||
| 
 | ||||
|   protected ?Delay $oduration; | ||||
| 
 | ||||
|   protected ?array $odatafilenames; | ||||
| 
 | ||||
|   protected function beforeAction() { | ||||
|     $this->loadMetadata(); | ||||
|     $this->ostart = cv::clone($this->start); | ||||
|     $this->oduration = cv::clone($this->duration); | ||||
|     $this->odatafilenames = cv::clone($this->datafilenames); | ||||
|   } | ||||
| 
 | ||||
|   protected function afterAction() { | ||||
|     $start = $this->start; | ||||
|     $duration = $this->duration; | ||||
|     $oduration = $this->oduration; | ||||
|     $datafilenames = $this->datafilenames; | ||||
|     $modified = false; | ||||
|     if ($start != $this->ostart) $modified = true; | ||||
|     if ($duration === null || $oduration === null) $modified = true; | ||||
|     elseif ($duration->getDest() != $oduration->getDest()) $modified = true; | ||||
|     # égalité stricte uniquement pour $datafiles qui est un array
 | ||||
|     if ($datafilenames !== $this->odatafilenames) $modified = true; | ||||
|     if ($modified && !$this->readonly) { | ||||
|       $this->lockWrite(); | ||||
|       $this->saveMetadata(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   protected function action(callable $callback, bool $willWrite=false) { | ||||
|     if ($willWrite && !$this->readonly) $this->lockWrite(); | ||||
|     else $this->lockRead(); | ||||
|     try { | ||||
|       $datafile = $data->getName(); | ||||
|       $datafile = "{$this->basename}.data.{$datafile}.cache"; | ||||
|       #XXX mettre à jour datafiles dans metadata
 | ||||
|       if ($this->shouldUpdate($noCache)) { | ||||
|       $this->beforeAction(); | ||||
|       $result = $callback(); | ||||
|       $this->afterAction(); | ||||
|       return $result; | ||||
|     } finally { | ||||
|       $this->start = null; | ||||
|       $this->duration = null; | ||||
|       $this->datafilenames = null; | ||||
|       $this->unlock(true); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   protected function compute() { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   function get($data=null, bool $noCache=false) { | ||||
|     return $this->action(function () use ($data, $noCache) { | ||||
|       $data = $this->getData($data); | ||||
|       $dataname = $data->getName(); | ||||
|       $datafilename = ".{$this->basename}.{$dataname}".self::EXT; | ||||
|       $datafile = path::join($this->basedir, $datafilename); | ||||
| 
 | ||||
|       $updateMetadata = $this->shouldUpdate($noCache); | ||||
|       $updateData = !array_key_exists($datafilename, $this->datafilenames); | ||||
|       if (!$this->readonly && ($updateMetadata || $updateData)) { | ||||
|         $this->lockWrite(); | ||||
|         try { | ||||
|           $data = $data->get(); | ||||
|           if ($this->shouldCache($data)) { | ||||
|             $this->saveData($datafile, $data); | ||||
|           } else { | ||||
|             # ne pas garder le fichier s'il ne faut pas mettre en cache
 | ||||
|             $this->unlinkDatafile($datafile); | ||||
|           } | ||||
|         } catch (Exception $e) { | ||||
|           $this->unlinkDatafile($datafile); | ||||
|           throw $e; | ||||
|         if ($updateMetadata) { | ||||
|           # il faut refaire tout le cache
 | ||||
|           $this->unlinkFiles(true); | ||||
|           $updateData = true; | ||||
|         } | ||||
|       } else { | ||||
|         if ($updateData) { | ||||
|           # calculer un fichier
 | ||||
|           try { | ||||
|             $data = $data->get(); | ||||
|           } catch (Exception $e) { | ||||
|             # ne pas garder le fichier en cas d'exception
 | ||||
|             $this->unlinkDatafile($datafile); | ||||
|             throw $e; | ||||
|           } | ||||
|         } elseif (file_exists($datafile)) { | ||||
|           $data = $this->loadData($datafile); | ||||
|         } else { | ||||
|           $data = null; | ||||
|         } | ||||
|         if ($this->shouldCache($data)) { | ||||
|           $this->saveData($datafile, $data); | ||||
|           $this->datafilenames[$datafilename] = true; | ||||
|         } else { | ||||
|           # ne pas garder le fichier s'il ne faut pas mettre en cache
 | ||||
|           $this->unlinkDatafile($datafile); | ||||
|         } | ||||
|       } elseif (file_exists($datafile)) { | ||||
|         $data = $this->loadData($datafile); | ||||
|       } else { | ||||
|         $data = null; | ||||
|       } | ||||
|       return $data; | ||||
|     } finally { | ||||
|       $this->unlock(); | ||||
|     } | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   /** obtenir les informations sur le fichier */ | ||||
|   function getInfos(): array { | ||||
|     $this->lockRead(); | ||||
|     try { | ||||
|     return $this->action(function () { | ||||
|       if (!$this->isValid()) { | ||||
|         return ["valid" => false]; | ||||
|       } | ||||
|       /** | ||||
|        * @var DateTime $start | ||||
|        * @var Delay $duration | ||||
|        */ | ||||
|       [ | ||||
|         "start" => $start, | ||||
|         "duration" => $duration, | ||||
|         "datafiles" => $datafiles, | ||||
|       ] = $this->loadMetadata(); | ||||
|       $start = $this->start; | ||||
|       $duration = $this->duration; | ||||
|       $datafilenames = $this->datafilenames; | ||||
|       $datafiles = []; | ||||
|       foreach (array_keys($datafilenames) as $datafilename) { | ||||
|         $datafile = path::join($this->basedir, $datafilename); | ||||
|         $name = $datafilename; | ||||
|         str::del_prefix($name, ".{$this->basename}."); | ||||
|         str::del_suffix($name, self::EXT); | ||||
|         if (file_exists($datafile)) { | ||||
|           $size = filesize($datafile); | ||||
|         } else { | ||||
|           $size = null; | ||||
|         } | ||||
|         $datafiles[$name] = $size; | ||||
|       } | ||||
|       return [ | ||||
|         "valid" => true, | ||||
|         "size" => $this->getSize(), | ||||
|         "start" => $start, | ||||
|         "duration" => strval($duration), | ||||
|         "date_start" => $start->format(), | ||||
|         "date_end" => $duration->getDest()->format(), | ||||
|         "datafiles" => $datafiles, | ||||
|       ]; | ||||
|     } finally { | ||||
|       $this->unlock(); | ||||
|     } | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   const UPDATE_SUB = -1, UPDATE_SET = 0, UPDATE_ADD = 1; | ||||
| 
 | ||||
|   /** mettre à jour la durée de validité du fichier */ | ||||
|   function updateDuration($nduration, int $action=1): void { | ||||
|     $this->lockRead(); | ||||
|     try { | ||||
|     if ($this->readonly) return; | ||||
|     $this->action(function () use ($nduration, $action) { | ||||
|       if (!$this->isValid()) return; | ||||
|       $this->lockWrite(); | ||||
|       /** | ||||
|        * @var DateTime $tstart | ||||
|        * @var Delay $duration | ||||
|        */ | ||||
|       [ | ||||
|         "start" => $start, | ||||
|         "duration" => $duration, | ||||
|       ] = $this->loadMetadata(); | ||||
|       $duration = $this->duration; | ||||
|       if ($action < 0) $duration->subDuration($nduration); | ||||
|       elseif ($action > 0) $duration->addDuration($nduration); | ||||
|       $this->saveMetadata($start, $duration); | ||||
|     } finally { | ||||
|       $this->unlock(); | ||||
|     } | ||||
|     }, true); | ||||
|   } | ||||
| 
 | ||||
|   /** supprimer les fichiers s'ils ont expiré */ | ||||
|   function deleteExpired(bool $force=false): bool { | ||||
|     $this->lockRead(); | ||||
|     try { | ||||
|     if ($this->readonly) return false; | ||||
|     return $this->action(function () use ($force) { | ||||
|       if ($force || $this->shouldUpdate()) { | ||||
|         $this->lockWrite(); | ||||
|         $this->unlinkFiles(); | ||||
|         return true; | ||||
|       } | ||||
|     } finally { | ||||
|       $this->unlock(); | ||||
|     } | ||||
|     return false; | ||||
|       return false; | ||||
|     }, true); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -47,9 +47,15 @@ class NucacheApp extends Application { | ||||
|   function setActionUpdate(int $action, $updateDuration): void { | ||||
|     $this->action = self::ACTION_UPDATE; | ||||
|     switch ($action) { | ||||
|     case self::ACTION_UPDATE_SUB: $this->updateAction = CacheFile::UPDATE_SUB; break; | ||||
|     case self::ACTION_UPDATE_SET: $this->updateAction = CacheFile::UPDATE_SET; break; | ||||
|     case self::ACTION_UPDATE_ADD: $this->updateAction = CacheFile::UPDATE_ADD; break; | ||||
|     case self::ACTION_UPDATE_SUB: | ||||
|       $this->updateAction = CacheFile::UPDATE_SUB; | ||||
|       break; | ||||
|     case self::ACTION_UPDATE_SET: | ||||
|       $this->updateAction = CacheFile::UPDATE_SET; | ||||
|       break; | ||||
|     case self::ACTION_UPDATE_ADD: | ||||
|       $this->updateAction = CacheFile::UPDATE_ADD; | ||||
|       break; | ||||
|     } | ||||
|     $this->updateDuration = $updateDuration; | ||||
|   } | ||||
| @ -72,7 +78,7 @@ class NucacheApp extends Application { | ||||
|       } elseif (is_file($arg)) { | ||||
|         $files[] = $arg; | ||||
|       } else { | ||||
|         msg::warning("$arg: fichier invalide ou introuvable"); | ||||
|         msg::warning("$arg: fichier introuvable"); | ||||
|       } | ||||
|     } | ||||
|     $showSection = count($files) > 1; | ||||
| @ -81,14 +87,17 @@ class NucacheApp extends Application { | ||||
|       case self::ACTION_READ: | ||||
|         if ($showSection) msg::section($file); | ||||
|         $cache = new CacheFile($file, [ | ||||
|           "readonly" => true, | ||||
|           "duration" => "INF", | ||||
|           "override_duration" => true, | ||||
|         ]); | ||||
|         //yaml::dump($cache->get());
 | ||||
|         yaml::dump($cache->get()); | ||||
|         break; | ||||
|       case self::ACTION_INFOS: | ||||
|         if ($showSection) msg::section($file); | ||||
|         $cache = new CacheFile($file); | ||||
|         $cache = new CacheFile($file, [ | ||||
|           "readonly" => true, | ||||
|         ]); | ||||
|         yaml::dump($cache->getInfos()); | ||||
|         break; | ||||
|       case self::ACTION_CLEAN: | ||||
| @ -96,7 +105,7 @@ class NucacheApp extends Application { | ||||
|         $cache = new CacheFile($file); | ||||
|         try { | ||||
|           if ($cache->deleteExpired()) msg::asuccess("fichier supprimé"); | ||||
|           else msg::astep("fichier non expiré"); | ||||
|           else msg::adone("fichier non expiré"); | ||||
|         } catch (Exception $e) { | ||||
|           msg::afailure($e); | ||||
|         } | ||||
|  | ||||
							
								
								
									
										1
									
								
								tbin/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								tbin/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,2 +1,3 @@ | ||||
| /output-forever.log | ||||
| /devel/ | ||||
| /*.cache | ||||
|  | ||||
							
								
								
									
										62
									
								
								tbin/test-nucache.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										62
									
								
								tbin/test-nucache.php
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,62 @@ | ||||
| #!/usr/bin/php
 | ||||
| <?php | ||||
| require __DIR__.'/../vendor/autoload.php'; | ||||
| 
 | ||||
| use nulib\file\cache\CacheData; | ||||
| use nulib\file\cache\CacheFile; | ||||
| use nulib\os\sh; | ||||
| 
 | ||||
| //system("rm -f *.cache .*.cache");
 | ||||
| 
 | ||||
| $what = [ | ||||
|   "null", | ||||
|   "one", | ||||
|   "two", | ||||
|   "three", | ||||
| ]; | ||||
| 
 | ||||
| if (in_array("null", $what)) { | ||||
|   $null = new CacheFile("null"); | ||||
|   Txx("null=", $null->get()); | ||||
| } | ||||
| 
 | ||||
| if (in_array("one", $what)) { | ||||
|   $one = new class("one") extends CacheFile { | ||||
|     protected function compute() { | ||||
|       return 1; | ||||
|     } | ||||
|   }; | ||||
|   Txx("one=", $one->get()); | ||||
| } | ||||
| 
 | ||||
| if (in_array("two", $what)) { | ||||
|   $two = new CacheFile("two", [ | ||||
|     "data" => new CacheData(function () { | ||||
|       return 2; | ||||
|     }), | ||||
|   ]); | ||||
|   Txx("two=", $two->get()); | ||||
| } | ||||
| 
 | ||||
| if (in_array("three", $what)) { | ||||
|   $data31 = new CacheData(function () { | ||||
|     return 31; | ||||
|   }, "data31name"); | ||||
| 
 | ||||
|   $data32 = new CacheData(function () { | ||||
|     return 32; | ||||
|   }); | ||||
| 
 | ||||
|   $three = new CacheFile("three", [ | ||||
|     "data" => [ | ||||
|       "data31" => $data31, | ||||
|       $data31, # name=data31name
 | ||||
|       "data32" => $data32, | ||||
|       $data32, # name=""
 | ||||
|     ], | ||||
|   ]); | ||||
|   Txx("three.0=", $three->get("data31")); | ||||
|   Txx("three.1=", $three->get("data31name")); | ||||
|   Txx("three.2=", $three->get("data32")); | ||||
|   Txx("three.3=", $three->get("")); | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user