Apache Zeta Components Manual :: File Source for apc_array.php

Source for file apc_array.php

Documentation is available at apc_array.php

  1. <?php
  2. /**
  3.  * File containing the ezcCacheStorageFileApcArray class.
  4.  *
  5.  * Licensed to the Apache Software Foundation (ASF) under one
  6.  * or more contributor license agreements.  See the NOTICE file
  7.  * distributed with this work for additional information
  8.  * regarding copyright ownership.  The ASF licenses this file
  9.  * to you under the Apache License, Version 2.0 (the
  10.  * "License"); you may not use this file except in compliance
  11.  * with the License.  You may obtain a copy of the License at
  12.  * 
  13.  *   http://www.apache.org/licenses/LICENSE-2.0
  14.  * 
  15.  * Unless required by applicable law or agreed to in writing,
  16.  * software distributed under the License is distributed on an
  17.  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  18.  * KIND, either express or implied.  See the License for the
  19.  * specific language governing permissions and limitations
  20.  * under the License.
  21.  *
  22.  * @package Cache
  23.  * @version //autogentag//
  24.  * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
  25.  * @filesource
  26.  */
  27.  
  28. /**
  29.  * This class is a replacement for the {@link ezcCacheStorageFileArray} class. Tries
  30.  * to serve data from a local APC cache if possible.
  31.  *
  32.  * Options for this class are defined in {@link ezcCacheStorageFileApcArrayOptions}.
  33.  *
  34.  * @apichange This class might be removed in future versions. Please use
  35.  *             {@link ezcCacheStack} to achieve the desired behaior.
  36.  * @package Cache
  37.  * @version //autogentag//
  38.  */
  39. {
  40.     /**
  41.      * Creates a new cache storage in the given location. The location in case
  42.      * of this storage class must a valid file system directory.
  43.      *
  44.      * Options can contain the 'ttl' (Time-To-Live). This is per default set
  45.      * to 1 day. The option 'permissions' can be used to define the file
  46.      * permissions of created cache items.
  47.      *
  48.      * For details about the options see {@link ezcCacheStorageFileApcArrayOptions}.
  49.      *
  50.      * @throws ezcBasePropertyNotFoundException
  51.      *          If you tried to set a non-existent option value.
  52.      *
  53.      * @param string $location Path to the cache location. Must be a valid path
  54.      * @param array(string=>string) $options Options for the cache storage
  55.      */
  56.     public function __construct$locationarray $options array() )
  57.     {
  58.         parent::__construct$locationarray() );
  59.  
  60.         // Overwrite parent set options with new ezcCacheStorageFileApcArrayOptions
  61.         $this->properties['options'new ezcCacheStorageFileApcArrayOptions$options );
  62.     }
  63.  
  64.     /**
  65.      * Fetches the data from the cache.
  66.      * 
  67.      * @param string $filename The ID/filename from where to fetch the object
  68.      * @param bool $useApc Use APC or the file system
  69.      * @return mixed The fetched data or false on failure
  70.      */
  71.     protected function fetchData$filename$useApc false )
  72.     {
  73.         if $useApc === true )
  74.         {
  75.             $data $this->backend->fetch$filename );
  76.             return is_object$data ) ) $data->data false;
  77.         }
  78.         else
  79.         {
  80.             return include $filename );
  81.         }
  82.     }
  83.  
  84.     /**
  85.      * Fetches the object from the cache.
  86.      *
  87.      * @param string $filename The ID/filename from where to fetch the data
  88.      * @return mixed The fetched object or false on failure
  89.      */
  90.     protected function fetchObject$filename )
  91.     {
  92.         $data $this->backend->fetch$filename );
  93.         return is_object$data ) ) $data false;
  94.     }
  95.  
  96.     /**
  97.      * Wraps the data in order to be stored in APC ($useApc = true) or on the
  98.      * file system ($useApc = false).
  99.      *
  100.      * @throws ezcCacheInvalidDataException
  101.      *          If the data submitted can not be handled by this storage (object,
  102.      *          resource).
  103.      *
  104.      * @param mixed $data Simple type or array
  105.      * @param bool $useApc Use APC or not
  106.      * @return mixed Prepared data
  107.      */
  108.     protected function prepareData$data$useApc false )
  109.     {
  110.         if $useApc === true )
  111.         {
  112.             if is_resource$data ) )
  113.             {
  114.                 throw new ezcCacheInvalidDataExceptiongettype$data )array'simple''array''object' ) );
  115.             }
  116.             return new ezcCacheStorageFileApcArrayDataStruct$data$this->properties['location');
  117.         }
  118.         else
  119.         {
  120.             if is_object$data )
  121.                  || is_resource$data ) )
  122.             {
  123.                 throw new ezcCacheInvalidDataExceptiongettype$data )array'simple''array' ) );
  124.             }
  125.             return "<?php\nreturn " var_export$datatrue ";\n?>\n";
  126.         }
  127.     }
  128.  
  129.     /**
  130.      * Stores data to the cache storage.
  131.      *
  132.      * @throws ezcBaseFilePermissionException
  133.      *          If the directory to store the cache file could not be created.
  134.      *          This exception means most likely that your cache directory
  135.      *          has been corrupted by external influences (file permission
  136.      *          change).
  137.      * @throws ezcBaseFileIoException
  138.      *          If an error occured while writing the data to the cache. If this
  139.      *          exception occurs, a serious error occured and your storage might
  140.      *          be corruped (e.g. broken network connection, file system broken,
  141.      *          ...).
  142.      * @throws ezcCacheInvalidDataException
  143.      *          If the data submitted can not be handled by the implementation
  144.      *          of {@link ezcCacheStorageFile}. Most implementations can not
  145.      *          handle objects and resources.
  146.      * @throws ezcCacheApcException
  147.      *          If the data could not be stored in APC.
  148.      *
  149.      * @param string $id Unique identifier
  150.      * @param mixed $data The data to store
  151.      * @param array(string=>string) $attributes Attributes describing the cached data
  152.      * @return string The ID string of the newly cached data
  153.      */
  154.     public function store$id$data$attributes array() )
  155.     {
  156.         // Generates the identifier
  157.         $filename $this->properties['location'$this->generateIdentifier$id$attributes );
  158.  
  159.         // Purges the Registry Cache
  160.         if isset$this->registry[$filename) )
  161.         {
  162.             unset$this->registry[$filename);
  163.         }
  164.  
  165.         // Deletes the files if it already exists on the filesystem
  166.         if file_exists$filename ) )
  167.         {
  168.             if unlink$filename === false )
  169.             {
  170.                 throw new ezcBaseFilePermissionException$filenameezcBaseFileException::WRITE'Could not delete existing cache file.' );
  171.             }
  172.         }
  173.  
  174.         // Deletes the data from APC if it already exists
  175.         $this->backend->delete$filename );
  176.  
  177.         // Prepares the data for filesystem storage
  178.         $dataStr $this->prepareData$data );
  179.  
  180.         // Tries to create the directory on the filesystem
  181.         $dirname dirname$filename );
  182.         if !is_dir$dirname )
  183.              && !mkdir$dirname0777true ) )
  184.         {
  185.             throw new ezcBaseFilePermissionException$dirnameezcBaseFileException::WRITE'Could not create directory to store cache file.' );
  186.         }
  187.  
  188.         // Tries to write the file the filesystem
  189.         if @file_put_contents$filename$dataStr !== strlen$dataStr ) )
  190.         {
  191.             throw new ezcBaseFileIoException$filenameezcBaseFileException::WRITE'Could not write data to cache file.' );
  192.         }
  193.  
  194.         // Tries to set the file permissions
  195.         if ezcBaseFeatures::os(!== "Windows" )
  196.         {
  197.             chmod$filename$this->options->permissions );
  198.         }
  199.  
  200.         // Prepares the data for APC storage
  201.         $dataObj $this->prepareData$datatrue );
  202.         $dataObj->mtime @filemtime$filename );
  203.         $dataObj->atime time();
  204.  
  205.         // Stores it in APC
  206.         $this->registerIdentifier$id$attributes$filename );
  207.         if !$this->backend->store$filename$dataObj$this->properties['options']['ttl') )
  208.         {
  209.             throw new ezcCacheApcException"APC store failed." );
  210.         }
  211.  
  212.         // Returns the ID for no good reason
  213.         return $id;
  214.     }
  215.  
  216.     /**
  217.      * Restores the data from the cache.
  218.      *
  219.      * @param string $id The item ID to restore
  220.      * @param array(string=>string) $attributes Attributes describing the data to restore
  221.      * @param bool $search Whether to search for items if not found directly
  222.      * @return mixed The cached data on success, otherwise false
  223.      */
  224.     public function restore$id$attributes array()$search false )
  225.     {
  226.         // Generates the identifier
  227.         $filename $this->properties['location'$this->generateIdentifier$id$attributes );
  228.  
  229.         // Grabs the data object from the APC
  230.         $dataObj $this->fetchObject$filename );
  231.         $useApc false;
  232.  
  233.         // Checks the APC object exists
  234.         if $dataObj !== false
  235.              && is_object$dataObj )
  236.              && isset$dataObj->atime ) )
  237.         {
  238.             $useApc true;
  239.         }
  240.  
  241.         // Checks the APC object is still valid
  242.         if !isset$this->registry[$filename)
  243.              && $useApc === true
  244.              && time(=== $dataObj->atime )
  245.         {
  246.             // Make sure the FileSystem still has the file and that it hasn't changed
  247.             if file_exists$filename !== false
  248.                  && @filemtime$filename === $dataObj->mtime )
  249.             {
  250.                 $dataObj->atime time();
  251.                 $this->backend->store$filename$dataObj$this->properties['options']['ttl');
  252.             }
  253.             else
  254.             {
  255.                 $useApc false;
  256.                 $this->backend->delete$filename );
  257.             }
  258.         }
  259.  
  260.         // Searches the filesystem for the file
  261.         if !isset$this->registry[$filename)
  262.              && $useApc === false
  263.              && file_exists$filename === false )
  264.         {
  265.             if $search === true
  266.                  && count$files $this->search$id$attributes ) ) === )
  267.             {
  268.                 $filename $files[0][2];
  269.             }
  270.             else
  271.             {
  272.                 // There are more elements found during search, so false is returned
  273.                 return false;
  274.             }
  275.         }
  276.  
  277.         // Returns false if no data is stored anywhere
  278.         if $useApc === false
  279.              && file_exists$filename === false )
  280.         {
  281.             // Purges APC
  282.             $this->backend->delete$filename );
  283.  
  284.             // Purges Registry Cache
  285.             if isset$this->registry[$filename) )
  286.             {
  287.                 unset$this->registry[$filename);
  288.             }
  289.  
  290.             return false;
  291.         }
  292.  
  293.         // Creates a Registry Object -- should only happen once per page load
  294.         if !isset$this->registry[$filename) )
  295.         {
  296.             $this->registry[$filenamenew stdClass();
  297.             $this->registry[$filename]->data false;
  298.             $this->registry[$filename]->mtime $useApc $dataObj->mtime null;
  299.             $this->registry[$filename]->lifetime $this->calcLifetime$filename$useApc );
  300.         }
  301.  
  302.         // Purges the data if it is expired
  303.         if $this->properties['options']['ttl'!== false
  304.              && $this->calcLifetime$filename$useApc $this->properties['options']['ttl')
  305.         {
  306.             $this->delete$id$attributesfalse )// don't search
  307.             return false;
  308.         }
  309.  
  310.         // Returns the data from the Registry Cache
  311.         if $this->registry[$filename]->data !== false )
  312.         {
  313.             return $this->registry[$filename]->data );
  314.         }
  315.  
  316.         // Returns data from APC
  317.         else if $useApc === true
  318.                   && isset$dataObj->data || is_null$dataObj->data ) ) )
  319.         {
  320.             $this->registry[$filename]->data $dataObj->data// primes the Registry cache
  321.             return $dataObj->data );
  322.         }
  323.  
  324.         // Returns data from the filesystem
  325.         else if file_exists$filename !== false )
  326.         {
  327.             // Grabs the data from the filesystem
  328.             $dataStr $this->fetchData$filename );
  329.  
  330.             // Stores it in the Registry Cache
  331.             $this->registry[$filename]->data $dataStr;
  332.  
  333.             // Prepares the data for APC storage
  334.             $dataObj $this->prepareData$dataStrtrue );
  335.             $dataObj->mtime @filemtime$filename );
  336.             $dataObj->atime time();
  337.  
  338.             // Stores it in APC
  339.             $this->backend->store$filename$dataObj$this->properties['options']['ttl');
  340.  
  341.             // Returns the data
  342.             return $dataStr );
  343.         }
  344.         else
  345.         {
  346.             return false;
  347.         }
  348.     }
  349.  
  350.     /**
  351.      * Deletes the data associated with $id or $attributes from the cache.
  352.      *
  353.      * @throws ezcBaseFilePermissionException
  354.      *          If an already existsing cache file could not be unlinked.
  355.      *          This exception means most likely that your cache directory
  356.      *          has been corrupted by external influences (file permission
  357.      *          change).
  358.      *
  359.      * @param string $id The item ID to purge
  360.      * @param array(string=>string) $attributes Attributes describing the data to restore
  361.      * @param bool $search Whether to search for items if not found directly
  362.      */
  363.     public function delete$id null$attributes array()$search false )
  364.     {
  365.         $location $this->properties['location'];
  366.         // Generates the identifier
  367.         $filename $location $this->generateIdentifier$id$attributes );
  368.  
  369.         // Initializes the array
  370.         $delFiles array();
  371.  
  372.         clearstatcache();
  373.  
  374.         // Checks if the file exists on the filesystem
  375.         if file_exists$filename ) )
  376.         {
  377.             $delFiles[array$id$attributes$filename );
  378.         }
  379.         else if $search === true )
  380.         {
  381.             $delFiles $this->search$id$attributes );
  382.         }
  383.  
  384.         $deletedIds array();
  385.         // Deletes the files
  386.         foreach $delFiles as $count => $filename )
  387.         {
  388.             // Deletes from Registry Cache
  389.             if isset$this->registry[$filename[2]] ) )
  390.             {
  391.                 unset$this->registry[$filename[2]] );
  392.             }
  393.  
  394.             // Deletes from APC
  395.             $this->backend->delete$filename[2);
  396.             $this->unRegisterIdentifier$filename[0]$filename[1]$filename[2]true );
  397.             if isset$this->registry[$location][$filename[0]][$filename[2]] ) )
  398.             {
  399.                 unset$this->registry[$location][$filename[0]][$filename[2]] );
  400.             }
  401.  
  402.             // Deletes from the filesystem
  403.             if @unlink$filename[2=== false )
  404.             {
  405.                 throw new ezcBaseFilePermissionException(
  406.                     $filename,
  407.                     ezcBaseFileException::WRITE,
  408.                     'Could not unlink cache file.'
  409.                 );
  410.             }
  411.             $deletedIds[$filename[0];
  412.         }
  413.         $this->storeSearchRegistry();
  414.         return $deletedIds;
  415.     }
  416.  
  417.     /**
  418.      * Checks the path in the location property exists, and is read-/writable. It
  419.      * throws an exception if not.
  420.      *
  421.      * @throws ezcBaseFileNotFoundException
  422.      *          If the storage location does not exist. This should usually not
  423.      *          happen, since {@link ezcCacheManager::createCache()} already
  424.      *          performs sanity checks for the cache location. In case this
  425.      *          exception is thrown, your cache location has been corrupted
  426.      *          after the cache was configured.
  427.      * @throws ezcBaseFileNotFoundException
  428.      *          If the storage location is not a directory. This should usually
  429.      *          not happen, since {@link ezcCacheManager::createCache()} already
  430.      *          performs sanity checks for the cache location. In case this
  431.      *          exception is thrown, your cache location has been corrupted
  432.      *          after the cache was configured.
  433.      * @throws ezcBaseFilePermissionException
  434.      *          If the storage location is not writeable. This should usually not
  435.      *          happen, since {@link ezcCacheManager::createCache()} already
  436.      *          performs sanity checks for the cache location. In case this
  437.      *          exception is thrown, your cache location has been corrupted
  438.      *          after the cache was configured.
  439.      */
  440.     protected function validateLocation()
  441.     {
  442.         if file_exists$this->properties['location'=== false )
  443.         {
  444.             throw new ezcBaseFileNotFoundException$this->properties['location']'cache location' );
  445.         }
  446.  
  447.         if is_dir$this->properties['location'=== false 
  448.         {
  449.             throw new ezcBaseFileNotFoundException$this->properties['location']'cache location''Cache location not a directory.' );
  450.         }
  451.  
  452.         if is_writeable$this->properties['location'=== false 
  453.         {
  454.             throw new ezcBaseFilePermissionException$this->properties['location']ezcBaseFileException::WRITE'Cache location is not a directory.' );
  455.         }
  456.     }
  457.  
  458.     /**
  459.      * Calculates the lifetime remaining for a cache object.
  460.      *
  461.      * If the TTL option is set to false, this method will always return 1 for
  462.      * existing items.
  463.      *
  464.      * @param string $filename The file to calculate the remaining lifetime for
  465.      * @param bool $useApc Use APC or not
  466.      * @return int The remaining lifetime in seconds (0 if no time remaining)
  467.      */
  468.     protected function calcLifetime$filename$useApc false )
  469.     {
  470.         $ttl $this->options->ttl;
  471.         // Calculate when the APC object was created
  472.         if $useApc === true )
  473.         {
  474.             // we've likely already looked this thing up in APC, so we'll grab the local object
  475.             if isset$this->registry[$filename) )
  476.             {
  477.                 $dataObj $this->registry[$filename];
  478.             }
  479.             else // otherwise we'll grab it from APC
  480.             {
  481.                 $dataObj $this->fetchObject$filename );
  482.             }
  483.  
  484.             if is_object$dataObj ) )
  485.             {
  486.                 if $ttl === false )
  487.                 {
  488.                     return 1;
  489.                 }
  490.                 return (
  491.                     $lifeTime time($dataObj->mtime ) ) $ttl
  492.                     ? $ttl $lifeTime 
  493.                     : 0
  494.                 );
  495.             }
  496.             else
  497.             {
  498.                 return 0;
  499.             }
  500.         }
  501.  
  502.         // Calculate when the filesystem file was created
  503.         else
  504.         {
  505.             if ( ( file_exists$filename !== false )
  506.                  && ( ( $modTime @filemtime$filename ) ) !== false ) )
  507.             {
  508.                 if $ttl === false )
  509.                 {
  510.                     return 1;
  511.                 }
  512.                 return (
  513.                     $lifeTime time($modTime ) ) $ttl
  514.                     ? $ttl $lifeTime 
  515.                     : 0
  516.                 );
  517.             }
  518.             else
  519.             {
  520.                 return 0;
  521.             }
  522.         }
  523.     }
  524. }
  525. ?>
Documentation generated by phpDocumentor 1.4.3