2009-02-12 13 views
23

मैं PHP में एक फोटो गैलरी स्क्रिप्ट लिख रहा हूं और एक ही निर्देशिका है जहां उपयोगकर्ता अपनी तस्वीरों को स्टोर करेगा। मैं पेज कैशिंग सेट अप करने का प्रयास कर रहा हूं और कैश को ताज़ा कर दिया गया है यदि निर्देशिका की सामग्री बदल गई है। मैंने सोचा कि मैं filemtime() फ़ंक्शन का उपयोग कर निर्देशिका के अंतिम संशोधित समय को कैश करके और निर्देशिका के वर्तमान संशोधित समय से इसकी तुलना करके ऐसा कर सकता हूं। हालांकि, जैसा कि मुझे एहसास हुआ है, निर्देशिका संशोधित समय बदल नहीं जाता है क्योंकि फ़ाइलों को उस निर्देशिका से जोड़ा या हटा दिया जाता है (कम से कम विंडोज़ पर, लिनक्स मशीनों के बारे में निश्चित नहीं है)।PHP के साथ निर्देशिका सामग्री बदल गई है या नहीं?

तो मेरे प्रश्न यह है कि किसी निर्देशिका की सामग्री को संशोधित करने के लिए सबसे आसान तरीका क्या है?

+0

प्रतिक्रियाओं के लिए धन्यवाद, लेकिन आपके अधिकांश उत्तर एक स्क्रिप्ट के लिए मान्य नहीं हैं कि कई अलग-अलग प्रणालियों पर कई अंतिम उपयोगकर्ता उपयोग करेंगे। मैं इसे कार्यान्वित करने के बारे में बेहतर समझने के लिए, http://code.web-geek.net/ck-gallery – PHLAK

उत्तर

6

उह

यहाँ एक सरल उदाहरण है। मैं बस एक निर्देशिका सूची के md5 स्टोर करेंगे। यदि सामग्री बदलती है, तो md5 (निर्देशिका-सूची) बदल जाएगी। आप बहुत ही सामान्य एमडी 5 संघर्ष प्राप्त कर सकते हैं, लेकिन मुझे लगता है कि मौका काफी छोटा है ..
वैकल्पिक रूप से, आप उस निर्देशिका में एक छोटी फ़ाइल स्टोर कर सकते हैं जिसमें "अंतिम संशोधित" तिथि हो। लेकिन मैं md5 के साथ जाना होगा।


पीएस। दूसरे विचार पर, आप देख रहे हैं कि आप प्रदर्शन (कैशिंग) को कैसे देख रहे हैं और निर्देशिका सूची को हैशिंग पूरी तरह इष्टतम नहीं हो सकता है ..

3

यहां आप क्या प्रयास कर सकते हैं। सभी चित्रों को एक ही निर्देशिका में स्टोर करें (या /username में उपनिर्देशिकाएं, चीजों को गति देने और एफएस पर तनाव को कम करने के लिए) और अपाचे (या जो भी आप उपयोग कर रहे हैं) सेट करें ताकि उन्हें "समय-समय पर स्थिर सामग्री" "भविष्य में 100 साल तक सेट करें। फ़ाइल नामों में कुछ अद्वितीय उपसर्ग या प्रत्यय (टाइमस्टैंप, फ़ाइल सामग्री का SHA1 हैश) होना चाहिए, इसलिए जब भी फ़ाइल का नाम बदलता है तो उसका नाम बदल जाता है और अपाचे एक नए संस्करण की सेवा करेगा, जो रास्ते में कैश किया जाएगा।

+0

पर गैलरी पृष्ठ देखें, यह ब्राउज़र स्ट्रिंग पैरामीटर और जैसे की वजह से ब्राउज़रों को कैशिंग नहीं करता है (सफारी, आईआईआरसी)। –

+0

पेज कैशिंग इस सब में कहां आती है? – Mario

+0

छवि नाम बदलना बुकमार्क को मार देगा। – Mario

3

आप गलत तरीके से सोच रहे हैं।

जैसे ही किसी ने एक नई फ़ाइल अपलोड की है और इसे लक्षित स्थान पर ले जाया गया है, आपको अपनी निर्देशिका अनुक्रमणिका स्क्रिप्ट निष्पादित करनी चाहिए।

+0

पहले एक अच्छा समाधान की तरह लगता है, लेकिन एक GOTCHA है। यदि वह कभी भी अपने पृष्ठ के टेम्पलेट को बदलना चाहता है, तो आपका समाधान विफल हो जाता है क्योंकि आप रीफ्रेश करने के लिए कैश किए गए आइटम को हटा नहीं सकते हैं। पूरी चीज के पुनर्निर्माण के लिए इसे एक और स्क्रिप्ट की आवश्यकता होगी। – Mario

+0

आप कैश किए गए आइटम को हटाने में सक्षम क्यों नहीं होना चाहिए? क्या आपने chmod के बारे में नहीं सुना है? – SchizoDuckie

+0

मैं सुझाव दे सकता हूं कि यह सावधानी से अपने प्रश्न, आपका उत्तर, नीचे मेरी प्रतिक्रिया और मेरी टिप्पणी को फिर से पढ़ा जाए। इस स्थिति में कैशिंग अपफ्रंट दोषपूर्ण है। – Mario

8

उपयोगकर्ता के बाद अपनी छवि सबमिट करने के बाद touching निर्देशिका के बारे में क्या? चेंजलॉग कहता है: विंडोज़ काम करने के लिए PHP 5.3 की आवश्यकता है, लेकिन मुझे लगता है कि इसे अन्य सभी वातावरणों पर काम करना चाहिए

+0

+1, सरल, अच्छा और तेज़! –

1

जब कोई उपयोगकर्ता अपनी निर्देशिका में फ़ाइल अपलोड करता है तो कैश किए गए संस्करण को हटाने का प्रयास करें।

जब कोई गैलरी देखने का प्रयास करता है, तो देखें कि पहले कैश किए गए संस्करण हैं या नहीं। यदि कोई कैश संस्करण है, तो इसे लोड करें, अन्यथा, पृष्ठ उत्पन्न करें, इसे कैश करें, किया गया।

+0

यह समझ में आता है, लेकिन मैं अपलोड की गई फ़ाइल के लिए कैसे निगरानी करूं? मेरी स्क्रिप्ट केवल तभी निष्पादित होती है जब कोई पृष्ठ पर जाता है, मैं सक्रिय रूप से निर्देशिका की निगरानी नहीं कर सकता, इसलिए मैंने डीआईआर की संशोधित तारीख की जांच करने की कोशिश की। – PHLAK

21

जैसा कि पहले से ही दूसरों द्वारा उल्लेख किया गया है, इसे हल करने का एक बेहतर तरीका एक घटना को ट्रिगर करना होगा जब विशेष घटनाएं होती हैं, जो फ़ोल्डर को बदलती है। हालांकि, यदि आपका सर्वर एक यूनिक्स है, तो आप निर्देशिका देखने के लिए inotifywait का उपयोग कर सकते हैं, और फिर एक PHP स्क्रिप्ट का आह्वान कर सकते हैं।

#!/bin/sh 
inotifywait --recursive --monitor --quiet --event modify,create,delete,move --format '%f' /path/to/directory/to/watch | 
    while read FILE ; do 
    php /path/to/trigger.php $FILE 
    done 

इन्हें भी देखें:: http://linux.die.net/man/1/inotifywait

+3

मुझे लगता है कि समाधान PHP स्तर पर रखा जाना चाहिए। यह समाधान अंतर्निहित ओएस के साथ PHP ऐप को उलझाता है और पोर्टेबिलिटी खो देता है। – Mario

+6

कुछ कार्यों को ओएस स्तर पर बहुत बेहतर तरीके से निपटाया जाता है। उदाहरण के लिए, cronjob सेट अप स्वाभाविक रूप से ओएस-विशिष्ट है। PHP में ऐसा करने का कोई तरीका नहीं है। – troelskn

+2

यह PHP के साथ एक HTML पृष्ठ कैशिंग करने के बारे में है, इसे PHP के साथ करना है। इसमें ओएस को शामिल करने से कुछ भी नहीं होगा। छुपा जादू का जिक्र नहीं करना इस समाधान से छेड़छाड़ प्रोग्रामर को भ्रमित कर सकती है। – Mario

1

मैं कुछ इसी तरह की तलाश में था और मैं सिर्फ इस पाया:

http://www.franzone.com/2008/06/05/php-script-to-monitor-ftp-directory-changes/

मेरे लिए एक महान समाधान की तरह दिखता है के बाद से मैं नियंत्रण का एक बहुत कुछ होगा (मैं एक AJAX कॉल करने जा रहे हैं यह देखने के लिए कि क्या कुछ बदल गया है)।

आशा है कि इससे मदद मिलती है।

+1

मैं उल्लेख करना भूल गया ... मेरी योजना इसे एफ़टीपी का उपयोग करने के बजाय स्थानीय निर्देशिका को पढ़ने के लिए बदलना है। लेकिन मूल बातें अभी भी वहां हैं। –

2

IMO edubem's answer जाने का रास्ता है, लेकिन आप कुछ इस तरह कर सकते हैं:

if (sha1(serialize(Map('/path/to/directory/', true))) != /* previous stored hash */) 
{ 
    // directory contents has changed 
} 

या एक और अधिक कमजोर/तेजी संस्करण:

if (Size('/path/to/directory/', true) != /* previous stored size */) 
{ 
    // directory contents has changed 
} 

यहाँ कार्यों उपयोग किया जाता है:

function Map($path, $recursive = false) 
{ 
    $result = array(); 

    if (is_dir($path) === true) 
    { 
     $path = Path($path); 
     $files = array_diff(scandir($path), array('.', '..')); 

     foreach ($files as $file) 
     { 
      if (is_dir($path . $file) === true) 
      { 
       $result[$file] = ($recursive === true) ? Map($path . $file, $recursive) : $this->Size($path . $file, true); 
      } 

      else if (is_file($path . $file) === true) 
      { 
       $result[$file] = Size($path . $file); 
      } 
     } 
    } 

    else if (is_file($path) === true) 
    { 
     $result[basename($path)] = Size($path); 
    } 

    return $result; 
} 

function Size($path, $recursive = true) 
{ 
    $result = 0; 

    if (is_dir($path) === true) 
    { 
     $path = Path($path); 
     $files = array_diff(scandir($path), array('.', '..')); 

     foreach ($files as $file) 
     { 
      if (is_dir($path . $file) === true) 
      { 
       $result += ($recursive === true) ? Size($path . $file, $recursive) : 0; 
      } 

      else if (is_file() === true) 
      { 
       $result += sprintf('%u', filesize($path . $file)); 
      } 
     } 
    } 

    else if (is_file($path) === true) 
    { 
     $result += sprintf('%u', filesize($path)); 
    } 

    return $result; 
} 

function Path($path) 
{ 
    if (file_exists($path) === true) 
    { 
     $path = rtrim(str_replace('\\', '/', realpath($path)), '/'); 

     if (is_dir($path) === true) 
     { 
      $path .= '/'; 
     } 

     return $path; 
    } 

    return false; 
} 
6

php

के अंदर inotifywait के साथ
$watchedDir = 'watch'; 

$in = popen("inotifywait --monitor --quiet --format '%e %f' --event create,moved_to '$watchedDir'", 'r'); 
if ($in === false) 
    throw new Exception ('fail start notify'); 

while (($line = fgets($in)) !== false) 
{ 
    list($event, $file) = explode(' ', rtrim($line, PHP_EOL), 2); 
    echo "$event $file\n"; 
} 
1

यहां एक कोड नमूना है, जो निर्देशिका को बदल दिया गया था, तो 0 वापस आ जाएगा। मैं इसे बैकअप में उपयोग करता हूं।

बदली गई स्थिति फ़ाइलों और उनकी फाइलों की उपस्थिति से निर्धारित होती है। आप आसानी से

$longString .= crc32(file_get_contents($file)); 

साथ

$longString .= filesize($file); 

की जगह फ़ाइल की सामग्री की तुलना करने के लिए इस बदल सकता है, लेकिन यह निष्पादन की गति को प्रभावित करेगा।

#!/usr/bin/php 
<?php 

$dirName = $argv[1]; 
$basePath = '/var/www/vhosts/majestichorseporn.com/web/'; 
$dataFile = './backup_dir_if_changed.dat'; 

# startup checks 
if (!is_writable($dataFile)) 
    die($dataFile . ' is not writable!'); 

if (!is_dir($basePath . $dirName)) 
    die($basePath . $dirName . ' is not a directory'); 

$dataFileContent = file_get_contents($dataFile); 
$data = @unserialize($dataFileContent); 
if ($data === false) 
    $data = array(); 

# find all files ang concatenate their sizes to calculate crc32 
$files = glob($basePath . $dirName . '/*', GLOB_BRACE); 

$longString = ''; 
foreach ($files as $file) { 
    $longString .= filesize($file); 
} 
$longStringHash = crc32($longString); 

# do changed check 
if (isset ($data[$dirName]) && $data[$dirName] == $longStringHash) 
    die('Directory did not change.'); 

# save hash do DB 
$data[$dirName] = $longStringHash; 

file_put_contents($dataFile, serialize($data)); 
die('0'); 
संबंधित मुद्दे