<p>θα ήθελα να χρησιμοποιήσω το curl όχι μόνο για την αποστολή παραμέτρων δεδομένων σε http post αλλά και για την αποστολή αρχείων με συγκεκριμένο όνομα φόρμας. πώς πρέπει να το κάνω;</p><p>http post parameters:</p><p>userid = 12345 filecomment = αυτό είναι ένα αρχείο εικόνας</p><p>http ανάρτηση αρχείου: τοποθεσία αρχείου = /home/user1/desktop/test.jpg όνομα φόρμας για αρχείο = εικόνα (αντιστοιχεί στο $ \_files ['image'] στην πλευρά php)</p><p>έκανα μέρος της εντολής curl ως εξής:</p><pre><code>curl -d "userid=1&amp;filecomment=this is an image file" --data-binary @"/home/user1/desktop/test.jpg" localhost/uploader.php </code></pre><p>το πρόβλημα που αντιμετωπίζω είναι το εξής:</p><pre><code>notice: undefined index: image in /var/www/uploader.php </code></pre><p>το πρόβλημα είναι ότι χρησιμοποιώ $ \_files ['image'] για να παραλάβω αρχεία στο σενάριο php.</p><p>πώς μπορώ να προσαρμόσω τις εντολές μου curl ανάλογα;</p>
χρησιμοποιώντας συστροφή για τη μεταφόρτωση δεδομένων post με αρχεία
<p>πρέπει να χρησιμοποιήσετε την επιλογή <code>-f</code>:<br> <code>-f/--form &lt;name=content&gt; specify http multipart post data (h)</code></p><p>δοκιμάστε αυτό:</p><pre><code>curl \ -f "userid=1" \ -f "filecomment=this is an image file" \ -f "image=@/home/user1/desktop/test.jpg" \ localhost/uploader.php </code></pre>
<p>πιάνοντας το αναγνωριστικό χρήστη ως μεταβλητή διαδρομής (συνιστάται):</p><pre><code>curl -i -x post -h "content-type: multipart/form-data" -f "data=@test.mp3" http://mysuperserver/media/1234/upload/ </code></pre><p>πιάνοντας το αναγνωριστικό χρήστη ως μέρος της φόρμας:</p><pre><code>curl -i -x post -h "content-type: multipart/form-data" -f "data=@test.mp3;userid=1234" http://mysuperserver/media/upload/ </code></pre><p>ή:</p><pre><code>curl -i -x post -h "content-type: multipart/form-data" -f "data=@test.mp3" -f "userid=1234" http://mysuperserver/media/upload/ </code></pre>
<p>εδώ είναι η λύση μου, έχω διαβάσει πολλές θέσεις και ήταν πραγματικά χρήσιμη. τελικά έγραψα κάποιο κώδικα για μικρά αρχεία, με curl και php που νομίζω ότι είναι πραγματικά χρήσιμος.</p><pre><code>public function postfile() { $file\_url = "test.txt"; //here is the file route, in this case is on same directory but you can set url too like "http://examplewebsite.com/test.txt" $eol = "\r\n"; //default line-break for mime type $boundary = md5(time()); //random boundaryid, is a separator for each param on my post curl function $body=""; //init my curl body $body.= '--'.$boundary. $eol; //start param header $body .= 'content-disposition: form-data; name="sometext"' . $eol . $eol; // last content with 2 $eol, in this case is only 1 content. $body .= "some data" . $eol;//param data in this case is a simple post data and 1 $eol for the end of the data $body.= '--'.$boundary. $eol; // start 2nd param, $body.= 'content-disposition: form-data; name="somefile"; filename="test.txt"'. $eol ; //first content data for post file, remember you only put 1 when you are going to add more contents, and 2 on the last, to close the content instance $body.= 'content-type: application/octet-stream' . $eol; //same before row $body.= 'content-transfer-encoding: base64' . $eol . $eol; // we put the last content and 2 $eol, $body.= chunk\_split(base64\_encode(file\_get\_contents($file\_url))) . $eol; // we write the base64 file content and the $eol to finish the data, $body.= '--'.$boundary .'--' . $eol. $eol; // we close the param and the post width "--" and 2 $eol at the end of our boundary header. $ch = curl\_init(); //init curl curl\_setopt($ch, curlopt\_httpheader, array( 'x\_param\_token : 71e2cb8b-42b7-4bf0-b2e8-53fbd2f578f9' //custom header for my api validation you can get it from $\_server["http\_x\_param\_token"] variable ,"content-type: multipart/form-data; boundary=".$boundary) //setting our mime type for make it work on $\_file variable ); curl\_setopt($ch, curlopt\_useragent, 'mozilla/1.0 (windows nt 6.1; wow64; rv:28.0) gecko/20100101 firefox/28.0'); //setting our user agent curl\_setopt($ch, curlopt\_url, "api.endpoint.post"); //setting our api post url curl\_setopt($ch, curlopt\_cookiejar, $boundary.'.txt'); //saving cookies just in case we want curl\_setopt ($ch, curlopt\_returntransfer, 1); // call return content curl\_setopt ($ch, curlopt\_followlocation, 1); navigate the endpoint curl\_setopt($ch, curlopt\_post, true); //set as post curl\_setopt($ch, curlopt\_postfields, $body); // set our $body $response = curl\_exec($ch); // start curl navigation print\_r($response); //print response } </code></pre><p>με αυτό θα έπρεπε να πάρουμε στο "api.endpoint.post" τα ακόλουθα vars δημοσιεύτηκε. μπορείτε εύκολα να δοκιμάσετε με αυτή τη δέσμη ενεργειών και θα πρέπει να λαμβάνετε αυτά τα σφάλματα στη λειτουργία <code>postfile()</code> στην τελευταία σειρά.</p><pre><code>print\_r($response); //print response public function getpostfile() { echo "\n\n\_server\n"; echo "&lt;pre&gt;"; print\_r($\_server['http\_x\_param\_token']); echo "/&lt;pre&gt;"; echo "\_post\n"; echo "&lt;pre&gt;"; print\_r($\_post['sometext']); echo "/&lt;pre&gt;"; echo "\_files\n"; echo "&lt;pre&gt;"; print\_r($\_filest['somefile']); echo "/&lt;pre&gt;"; } </code></pre><p>θα πρέπει να δουλέψει καλά, μπορεί να είναι καλύτερες λύσεις, αλλά αυτό λειτουργεί και είναι πραγματικά χρήσιμο να κατανοήσουμε τον τρόπο με τον οποίο ο ομιλητής borderary και multipart/from-data εργάζεται στη βιβλιοθήκη php και curl.</p>
<p>αν μεταφορτώνετε δυαδικό αρχείο όπως csv, χρησιμοποιήστε τη παρακάτω φόρμα για να μεταφορτώσετε το αρχείο</p><pre><code>curl -x post \ 'http://localhost:8080/workers' \ -h 'authorization: eyjhbgcioijiuzi1niisinr5cci6imfjy2vzcyisinr5cguioijhy2nlc3mifq.eyj1c2vyswqiojesimfjy291bnrjzci6mswiawf0ijoxntexmzmwmzg5lcjlehaioje1mtm5mjizodksimf1zci6imh0dhbzoi8vew91cmrvbwfpbi5jb20ilcjpc3mioijmzwf0agvycyisinn1yii6imfub255bw91cyj9.hwk7qj0uk6sei8qseeb6-tgsldlzotpg51u6kvi8nyc' \ -h 'content-type: application/x-www-form-urlencoded' \ --data-binary '@/home/limitless/downloads/iroute masters - workers.csv' </code></pre>
<p>ως εναλλακτική λύση για την <code>curl</code>, μπορείτε να χρησιμοποιήσετε <a href="https://github.com/jakubroztocil/httpie#file-upload-forms">httpie</a> , είναι cli, curl-σαν εργαλείο για τον άνθρωπο.</p><ol> <li> <p>οδηγίες εγκατάστασης: <a href="https://github.com/jakubroztocil/httpie#installation">https://github.com/jakubroztocil/httpie#installation</a> </p> </li> <li> <p>στη συνέχεια, εκτελέστε:</p> <pre><code>http -f post http://localhost:4040/api/users username=johnsnow photo@images/avatar.jpg http/1.1 200 ok access-control-expose-headers: x-frontend cache-control: no-store connection: keep-alive content-encoding: gzip content-length: 89 content-type: text/html; charset=windows-1251 date: tue, 26 jun 2018 11:11:55 gmt pragma: no-cache server: apache vary: accept-encoding x-frontend: front623311 ... </code></pre></li> </ol>
<p>εδώ μπορείτε να διαγράψετε σωστά τα αυθαίρετα ονόματα αρχείων των φορτωμένων αρχείων με <code>bash</code>:</p><pre><code>#!/bin/bash set -eu f="$1" f=${f//\\/\\\\} f=${f//\"/\\\"} f=${f//;/\\;} curl --silent --form "uploaded=@\"$f\"" "$2" </code></pre>