2011-03-26 19 views
16

यहाँ एक जोड़े को अजीब बातें हुआ, जब मैं कुछ भी नहीं अपलोड मैं उपयोग count($_FILES['image']), मैं उस समारोह गूँजती के माध्यम से

Main photo: <input type="file" name="image[]" /> 
Side photo 1: <input type="file" name="image[]" /> 
Side photo 2: <input type="file" name="image[]" /> 
Side photo 3: <input type="file" name="image[]" /> 

आदानों पाश करने के लिए मैं चाहता हूँ कर रहे हैं, और यह देता है उसे 5 के मूल्य कोई होना चाहिए उस सरणी में तत्व। एक अतिरिक्त इनपुट क्यों है जब मेरे पास केवल 4 फाइलें शुरू होंगी?

अब वास्तव में लूपिंग के साथ, मैं फ़ोरैच लूप का उपयोग करने का प्रयास करता हूं, लेकिन यह काम नहीं करता है।

foreach($_FILES['image'] as $files){echo $files['name']; } 

कुछ भी नहीं आया था, क्या मुझे यकीन है कि वे सही स्वरूप, आकार के होते हैं, और उनमें से प्रत्येक का नाम बदलने के बनाने के लिए अंत में कर सभी छवियों के माध्यम से लूप करने के लिए है चाहता था। लेकिन यह सरल foreach() लूप दिखाता है कि किसी भी तरह से मैं $ _FILES सरणी के माध्यम से लूप भी नहीं कर सकता और गिनती() ने मुझे और भी भ्रमित कर दिया जब यह कहता है कि सरणी में 5 तत्व हैं जब मैंने कुछ भी अपलोड नहीं किया था।

+6

आप 'var_dump ($ _ फ़ाइलें)' की कोशिश की? एक छोटा डीबगिंग यह पता लगाने का एक लंबा रास्ता तय करता है कि PHP क्या कर रहा है। – Matthew

उत्तर

38

आपका उदाहरण फ़ॉर्म ठीक काम करना चाहिए। यह सिर्फ इतना है कि आप $_FILES सुपरग्लोबल की संरचना की उम्मीद कर रहे हैं, जो फ़ील्ड नामों के लिए सरणी संरचना का उपयोग करते समय वास्तव में अलग है।

इस बहुआयामी सरणी की संरचना के रूप में तो पीछा किया जाता है:

$_FILES[fieldname] => array(
    [name] => array(/* these arrays are the size you expect */) 
    [type] => array(/* these arrays are the size you expect */) 
    [tmp_name] => array(/* these arrays are the size you expect */) 
    [error] => array(/* these arrays are the size you expect */) 
    [size] => array(/* these arrays are the size you expect */) 
); 

वजह count($_FILES[ "fieldname" ])5 निकलेगा।
लेकिन गहरे आयामों की गिनती से आप जिस नतीजे की उम्मीद कर सकते हैं उसका उत्पादन भी नहीं करेंगे। उदाहरण के लिए count($_FILES[ "fieldname" ][ "tmp_name" ]) वाले फ़ील्ड की गणना करना हमेशा फाइल फ़ील्ड की संख्या में होगा, न कि वास्तव में अपलोड की गई फ़ाइलों की संख्या में। आपको अभी भी यह निर्धारित करने के लिए तत्वों के माध्यम से लूप करना होगा कि किसी विशेष फ़ाइल फ़ील्ड के लिए कुछ भी अपलोड किया गया है या नहीं।

संपादित
तो, खेतों लूप करने के लिए आप निम्नलिखित की तरह कुछ करना होगा:

// !empty($_FILES) is an extra safety precaution 
// in case the form's enctype="multipart/form-data" attribute is missing 
// or in case your form doesn't have any file field elements 
if(strtolower($_SERVER[ 'REQUEST_METHOD' ]) == 'post' && !empty($_FILES)) 
{ 
    foreach($_FILES[ 'image' ][ 'tmp_name' ] as $index => $tmpName) 
    { 
     if(!empty($_FILES[ 'image' ][ 'error' ][ $index ])) 
     { 
      // some error occured with the file in index $index 
      // yield an error here 
      return false; // return false also immediately perhaps?? 
     } 

     /* 
      edit: the following is not necessary actually as it is now 
      defined in the foreach statement ($index => $tmpName) 

      // extract the temporary location 
      $tmpName = $_FILES[ 'image' ][ 'tmp_name' ][ $index ]; 
     */ 

     // check whether it's not empty, and whether it indeed is an uploaded file 
     if(!empty($tmpName) && is_uploaded_file($tmpName)) 
     { 
      // the path to the actual uploaded file is in $_FILES[ 'image' ][ 'tmp_name' ][ $index ] 
      // do something with it: 
      move_uploaded_file($tmpName, $someDestinationPath); // move to new location perhaps? 
     } 
    } 
} 

अधिक जानकारी के लिए the docs देखते हैं।

+0

ठीक है कि यह कैसे काम करता है की एक सुंदर अच्छी व्याख्या है। तो मैं प्रत्येक फ़ाइल इनपुट के माध्यम से वास्तव में कैसे लूप होगा? मुझे लगता है कि सबसे अच्छा अभ्यास उन्हें छवि के बजाय अलग-अलग नाम (छवि 1, छवि 2, छवि 3) देना है []? – Ben

+0

@ बेन "मुझे लगता है कि सबसे अच्छा अभ्यास है [..]" जरूरी नहीं है। मैं वास्तव में भी आपके मूल दृष्टिकोण का उपयोग करना पसंद करता हूं। मैं अपने उत्तर को एक उदाहरण के साथ अपडेट करूंगा कि इसके माध्यम से लूप कैसे करें। –

+0

@ बेन, मैंने अपना जवाब अपडेट कर दिया है। इसके साथ गुड लक। –

11

सिर्फ अपने खेतों इस तरह

Main photo: <input type="file" name="image1" /> 
Side photo 1: <input type="file" name="image2" /> 
Side photo 2: <input type="file" name="image3" /> 
Side photo 3: <input type="file" name="image4" /> 

नाम बदलने और फिर आप इसे हमेशा की तरह तेज़ी से दोहराने में सक्षम हो जाएगा:

foreach($_FILES as $file){ 
    echo $file['name']; 
} 
+0

फ़ील्ड खाली होने पर गिनती ($ _ FILES) कैसे काम नहीं करती है, यह 1 हो जाती है। और अब आप छवि के साथ फाइल इनपुट के माध्यम से लूप कर सकते हैं [] ??? – Ben

+0

: ठीक है, लेकिन वर्णित व्यवहार के कारण क्या हुआ? –

+0

@ टोमलाक जिस तरह से सरणी आबादी जा रही है। दोनों तरीकों से बस 'print_r ($ _ FILES) 'देखें और देखें। –

1

शायद:

Main photo: <input type="file" name="image1" /> 
Side photo 1: <input type="file" name="image2" /> 
Side photo 2: <input type="file" name="image3" /> 
Side photo 3: <input type="file" name="image4" /> 

$i=1; 
while (isset($_FILES['image'.$i])) { 
    print_r($_FILES['image'.$i]); 
    $i++; 
} 

यदि आपको विशिष्ट फ़ाइल फ़ील्ड के माध्यम से लूप करना है।

2

मैं ऐसे समाधान के साथ आया जो मनमाने ढंग से गहराई के $ _FILES सरणी के लिए काम करता है।

For each subtree in the file tree that's more than one item deep: 
    For each leaf of the subtree: 
    $leaf[a][b][c] ... [y][z] -> $result[z][a][b][c] ... [y] 

यहाँ कुछ कोड है कि वास्तव में काम करता है: एक त्वरित विवरण के रूप में, क्या आप एक एल्गोरिथ्म है कि यह करता है की जरूरत है।

function sane_file_array($files) { 
    $result = array(); 
    $name = array(); 
    $type = array(); 
    $tmp_name = array(); 
    $error = array(); 
    $size = array(); 
    foreach($files as $field => $data) { 
    foreach($data as $key => $val) { 
     $result[$field] = array(); 
     if(!is_array($val)) { 
     $result[$field] = $data; 
     } else { 
     $res = array(); 
     files_flip($res, array(), $data); 
     $result[$field] += $res; 
     } 
    } 
    } 

    return $result; 
} 

function array_merge_recursive2($paArray1, $paArray2) { 
    if (!is_array($paArray1) or !is_array($paArray2)) { return $paArray2; } 
    foreach ($paArray2 AS $sKey2 => $sValue2) { 
    $paArray1[$sKey2] = array_merge_recursive2(@$paArray1[$sKey2], $sValue2); 
    } 
    return $paArray1; 
} 

function files_flip(&$result, $keys, $value) { 
    if(is_array($value)) { 
    foreach($value as $k => $v) { 
     $newkeys = $keys; 
     array_push($newkeys, $k); 
     files_flip($result, $newkeys, $v); 
    } 
    } else { 
    $res = $value; 
    // Move the innermost key to the outer spot 
    $first = array_shift($keys); 
    array_push($keys, $first); 
    foreach(array_reverse($keys) as $k) { 
     // You might think we'd say $res[$k] = $res, but $res starts out not as an array 
     $res = array($k => $res);  
    } 

    $result = array_merge_recursive2($result, $res); 
    } 
} 

बस $ _FILES पर sane_files_array कॉल करेगा और आपको जाना अच्छा होना चाहिए, कितना गहरा $ _FILES सरणी है की परवाह किए बिना। यह वास्तव में भाषा का हिस्सा होना चाहिए, क्योंकि $ _FILES सरणी का स्वरूपण बिल्कुल हास्यास्पद है।

0

$ _FILES को संभालने के तरीके की PHP की पसंद बहुत सारे डेवलपर समय को बर्बाद कर देती है। @ लेंड्रिक के जवाब के आधार पर, यहां एक समान ओओ दृष्टिकोण है।

/** 
* @brief get the POSTed files in a more usable format 
    Works on the following methods: 
     <form method="post" action="/" name="" enctype="multipart/form-data"> 
     <input type="file" name="photo1" /> 
     <input type="file" name="photo2[]" /> 
     <input type="file" name="photo2[]" /> 
     <input type="file" name="photo3[]" multiple /> 
* @return Array 
* @todo 
* @see http://stackoverflow.com/questions/5444827/how-do-you-loop-through-files-array 
*/ 
public static function GetPostedFiles() 
{ 
    /* group the information together like this example 
    Array 
    (
     [attachments] => Array 
     (
      [0] => Array 
      (
       [name] => car.jpg 
       [type] => image/jpeg 
       [tmp_name] => /tmp/phpe1fdEB 
       [error] => 0 
       [size] => 2345276 
      ) 
     ) 
     [jimmy] => Array 
     (
      [0] => Array 
      (
       [name] => 1.jpg 
       [type] => image/jpeg 
       [tmp_name] => /tmp/phpx1HXrr 
       [error] => 0 
       [size] => 221041 
      ) 
      [1] => Array 
      (
       [name] => 2 ' .jpg 
       [type] => image/jpeg 
       [tmp_name] => /tmp/phpQ1clPh 
       [error] => 0 
       [size] => 47634 
      ) 
     ) 
    ) 
    */ 

    $Result = array(); 
    $Name = array(); 
    $Type = array(); 
    $TmpName = array(); 
    $Error = array(); 
    $Size = array(); 
    foreach($_FILES as $Field => $Data) 
    { 
     foreach($Data as $Key => $Val) 
     { 
      $Result[$Field] = array(); 
      if(!is_array($Val)) 
       $Result[$Field] = $Data; 
      else 
      { 
       $Res = array(); 
       self::GPF_FilesFlip($Res, array(), $Data); 
       $Result[$Field] += $Res; 
      } 
     } 
    } 

    return $Result; 
} 

private static function GPF_ArrayMergeRecursive($PaArray1, $PaArray2) 
{ 
    // helper method for GetPostedFiles 
    if (!is_array($PaArray1) or !is_array($PaArray2)) 
     return $PaArray2; 
    foreach ($PaArray2 AS $SKey2 => $SValue2) 
     $PaArray1[$SKey2] = self::GPF_ArrayMergeRecursive(@$PaArray1[$SKey2], $SValue2); 
    return $PaArray1; 
} 

private static function GPF_FilesFlip(&$Result, $Keys, $Value) 
{ 
    // helper method for GetPostedFiles 
    if(is_array($Value)) 
    { 
     foreach($Value as $K => $V) 
     { 
      $NewKeys = $Keys; 
      array_push($NewKeys, $K); 
      self::GPF_FilesFlip($Result, $NewKeys, $V); 
     } 
    } 
    else 
    { 
     $Res = $Value; 
     // move the innermost key to the outer spot 
     $First = array_shift($Keys); 
     array_push($Keys, $First); 
     foreach(array_reverse($Keys) as $K) 
      $Res = array($K => $Res); // you might think we'd say $Res[$K] = $Res, but $Res starts out not as an array 
     $Result = self::GPF_ArrayMergeRecursive($Result, $Res); 
    } 
} 
6

कुछ और अपेक्षित संरचना के लिए $ _FILES ['files'] को पुनर्निर्माण करने के लिए लघु कार्य।

function restructureFilesArray($files) 
{ 
    $output = []; 
    foreach ($files as $attrName => $valuesArray) { 
     foreach ($valuesArray as $key => $value) { 
      $output[$key][$attrName] = $value; 
     } 
    } 
    return $output; 
} 
0

मैंने लगभग एक सप्ताह तक इस दुविधा के साथ संघर्ष किया है! नेट पर जो कुछ भी मिला वह मेरी मदद कर सकता था। मुझे पता था कि क्या करना है, लेकिन यह समझ नहीं सका कि $ _FILES सरणी के माध्यम से कैसे लूप करना है - अब तक जब मैं स्वीकृत उत्तर के संपादित पोस्ट को पढ़ता हूं।

मैंने लिपि में पोस्ट किए गए कुछ बदलाव किए हैं, क्योंकि यह मेरे लिए ठीक से काम नहीं करता है। मैं यह निर्धारित करने में सक्षम होना चाहता था कि फ़ाइल को बिल्कुल चुना गया था, इसलिए मैंने लाइन "अगर (! खाली ($ _FILES ['image'] ['error'] [$ index]) बदल दिया है)" से " अगर (! खाली ($ _FILES ['image'] ['size'] [$ index])) " और उसके बाद" झूठी वापसी "की बजाय, मैंने आकार को इसके बजाय एक चर में रखा: " $ आकार = $ _FILES ['अपलोड'] ['आकार'] [$ अनुक्रमणिका]; "

इस तरह से मैं जांच सकता हूं कि $ आकार चर शून्य से बड़ा था या नहीं। यदि यह था, तो एक फ़ाइल का चयन किया गया था और मैं फ़ाइलों की संख्या गिनने और वास्तविक अपलोड करने के साथ जारी रख सकता था। स्वीकार्य उत्तर में, मैंने "वापसी झूठी" के बाद किसी भी "अनावश्यक" स्क्रिप्ट का उपयोग नहीं किया। उम्मीद है कि यह किसी की मदद करता है।

: पी /MACD

संबंधित मुद्दे