FTP-class

Gepost door Jan Willem van der Veer op 03-04-2010 11:38.

Een FTP-class. Min of meer geschreven voor de lol.
Volgens RFC 959 en enkele latere drafts (waar de FTP-functie MLSD vandaan komt).

Veel succes voor een ieder die deze class wil gebruiken.

Deze class is ook onder PHP 4 te gebruiken (waarvoor hij origineel ook geschreven was). Moet je wel even de privates en publics veranderen/verwijderen.

Het melden van bugs of aanvragen van extra functionaliteit wordt op prijs gesteld :)

Bestanden van dit script

index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
<?php

class FTPSocket {
    private $connection;
    private $dataconnection;
    public $port = 21;

    /**
     * public function connect
     * Connect with FTP-server at $host with username $user and password or accountname $pass
     *
     * @param    string    $host    Hostname to connect with
     * @param    string    $user    Username for login
     * @param    string    $pass    Password or account for login
     * @return    boolean            True on succes, false otherwise.
     */
    public function connect($host, $user = false, $pass = false){
        if($this->connection) @fclose($this->connection);
        if($this->connection = @fsockopen($host, (is_int($this->port)? $this->port : 21), $error, $errorstr, 5)){
            socket_set_blocking($this->connection, 0);
            if((intval($this->reply()) == 220) && is_string($user) && ($replyCode = intval($this->command('USER ' . $user)))){
                if($replyCode == 331) $replyCode = intval($this->command('PASS ' . (is_string($pass)? $pass : 'anonymous')));
                elseif(is_string($pass)) $replyCode = intval($this->command('ACCT ' . $pass));
                $this->features(true);
                return (($replyCode == 230) || ($replyCode == 202));
            }
        }
        return false;
    }

    /**
     * private function reply
     * Get the reply after a command. Only for internal use.
     *
     * @param    string    $retry    Indication whether the function has to retry to get the data
     * @return    string            Reply. Is NULL if no connection has been opened.
     */
    private function reply($retry = true){
        if($this->connection){
            $reply = '';
            while(true){
                while(is_string($replypart = @fgets($this->connection, 512)) && (strlen($replypart) > 0)){
                    $reply .= $replypart;
                    if(is_string($replypart) && is_numeric(substr($replypart, 0, 3)) && (ord(substr($replypart, 3, 1)) == 32)) return $reply;
                } if(!$retry) break;
            }
        }
        return NULL;
    }

    /**
     * public function umask
     * Set UMASK for creating directories and files
     *
     * @param    int        $umask    New umask
     * @return    boolean            True on succes, false otherwise.
     */
    public function umask($umask){
        return (is_numeric($umask) && (intval($this->command('UMASK 0' . str_pad(decoct(intval($umask)), 3, '0', STR_PAD_LEFT)))));
    }

    /**
     * public function command
     * Send command to FTP-server and get its reply.
     *
     * @param    string    $commandstring
     * @return    string                    FTP-serverreply or NULL if failed.
     */
    public function command($commandstring){
        $this->reply(false);
        if(is_string($commandstring) && $this->connection && fwrite($this->connection, $commandstring . "\r\n")) return $this->reply();
        return NULL;
    }

    /**
     * public function cdup
     * Same as cwdir('..')
     *
     * @return    boolean    True on succes, false otherwise.
     */
    public function cdup(){
        return (intval($this->command('CDUP')) == 200);
    }

    /**
     * public function cwdir
     * Change the current workdirectory.
     *
     * @param    string    $path    New directory, if it starts with '/' it will be treated as an absolute path, otherwise relative.
     * @return    boolean            True on succes, false otherwise
     */
    public function cwdir($path){
        return (is_string($path) && (intval($this->command('CWD ' . $path)) == 250));
    }

    /**
     * public function rmdir
     * Remove given directory
     *
     * @param    string    $path    Path to the directory.
     * @return    boolean            True on succes, false otherwise.
     */
    public function rmdir($path){
        return (is_string($path) && (intval($this->command('RMD ' . $path)) == 250));
    }

    /**
     * public function mkdir
     * Create directory
     *
     * @param    string    $path    Path to new directory
     * @param    int        $umask    Umask to create directory with. See self::umask.
     * @return    boolean            True on succes, false otherwise.
     */
    public function mkdir($path, $umask = false){
        return (is_string($path) && (!is_numeric($umask) || $this->umask($umask)) && (intval($this->command('MKD ' . $path)) == 257));
    }

    /**
     * public function delete
     * Delete particular file on the FTP-server
     *
     * @param    string    $path    Path to the file that has to be deleted
     * @return    boolean            True on succes, false otherwise.
     */
    public function delete($path){
        return (is_string($path) && (intval($this->command('DELE ' . $path)) == 250));
    }

    /**
     * public function chmod
     * Chmod a particular path on the FTP-server. Is not a standard FTP-option!
     *
     * @param    string    $path
     * @param    int        $chmod
     * @return    boolean            True on succes, false if not supported or failed.
     */
    public function chmod($path, $chmod){
        return (is_numeric($chmod) && (intval($this->command('SITE CHMOD 0' . str_pad(decoct(intval($chmod)), 3, '0', STR_PAD_LEFT) . ' ' . $path)) == 200));
    }

    /**
     * public function rename
     * Rename a path to an other path. Like PHP-function rename (http://www.php.net/rename)
     *
     * @param    string    $path
     * @param    string    $newpath
     * @return    boolean            True on succes, false otherwise.
     */
    public function rename($path, $newpath){
        return (is_string($path) && is_string($newpath) && (intval($this->command('RNFR ' . $path)) == 350) && (intval($this->command('RNTO ' . $newpath)) == 250));
    }

    /**
     * public function file_exists
     * Checks wheter a path has been exists, using FTP-function RNFR.
     *
     * @param    string    $path
     * @return    boolean            True on succes, false otherwise.
     */
    public function file_exists($path){
        return (intval($this->command('RNFR ' . $path)) == 350);
    }

    /**
     * public function pwdir
     * Get the current workdirectory.
     *
     * @return    string    Current workdirectory, NULL on failure.
     */
    public function pwdir(){
        if((intval($reply = $this->command('PWD')) == 257) && is_int($spos = strpos($reply, '"')) && is_int($epos = strrpos($reply, '"', ($spos + 1)))) return str_replace('""', '"', substr($reply, ($spos + 1), ($epos - $spos - 1)));
        return NULL;
    }

    /**
     * public function mtime
     * Get last modification-time of a file.
     *
     * @param    string    $path
     * @return    int        UNIX timestamp, NULL on failure.
     */
    public function mtime($path){
        if(is_string($path) && (intval($reply = $this->command('MDTM ' . $path)) == 213) && is_numeric($time = substr($reply, 4, 14)) && is_int($time = mktime(substr($time, 8, 2), substr($time, 10, 2), substr($time, 12, 2), substr($time, 4, 2), substr($time, 6, 2), substr($time, 0, 4)))) return $time;
        return NULL;
    }

    /**
     * public function features
     * Get supported feature of the FTP-server
     *
     * @param    boolean    $reget
     * @return    Array            Array of features with pattern Array(FEATURE_NAME => EXTENSIONS) or NULL on failure.
     */
    public function features($reget = false){
        static $feats = Array();
        if(!$reget && count($feats)) return $feats;
        if(intval($reply = $this->command('FEAT')) == 211){
            $feats = Array();
            $feat = preg_split("#\s*([\r\n]+)\s*#", trim($reply));
            $i = 0;
            while(($i += 1) < (count($feat) - 1)) $feats[(is_int($pos = strpos($feat[$i], chr(32)))? substr($feat[$i], 0, $pos) : $feat[$i])] = (is_int($pos)? substr($feat[$i], ($pos + 1)) : '');
            return $feats;
        }
        return NULL;
    }

    /**
     * public function abort
     * Abort dataconnection
     *
     * @return    boolean    True on succes, false otherwise.
     */
    public function abort(){
        if($this->dataconnection && in_array(($reply = intval($this->command('ABOR'))), Array(225, 226))){
            if($reply == 226) @fclose($this->dataconnection);
            $this->dataconnection = NULL;
            return true;
        }
        return false;
    }

    /**
     * public function systype
     * Get systemtype of the FTP-server.
     *
     * @return    string    Normally a string with WIN or UNIX is being returned, NULL on failure.
     */
    public function systype(){
        if(intval($reply = $this->command('SYST')) == 215) return (trim(substr($reply, 4)));
        return NULL;
    }

    /**
     * public function storeunique
     * Store file or data in an unique file.
     *
     * @param    string    $fileordata    An existed file or data that has to be stored.
     * @param    string    $path        The directory in which the file has to be stored.
     * @return boolean                True on succes, false otherwise
     */
    public function storeunique($fileordata, $path = false){
        if(is_string($path) && !$this->cwdir($path))
        return false;
        if(is_string($fileordata)){
            $replyCode = 425;
            if($this->dataconnection && $this->type('I') && (intval($this->command('ALLO ' . (is_file($fileordata)? filesize($fileordata) : strlen($fileordata))))) && in_array(($replyCode = intval($this->command('STOU'))), Array(125, 150))){
                if(!is_file($fileordata)) fwrite($this->dataconnection, $fileordata);
                elseif($fp = @fopen($fileordata, 'rb')) while(is_string($filepart = @fgets($fp))) fwrite($this->dataconnection, $filepart);
                elseif($this->abort()) return false;
                @fclose($this->dataconnection);
                $this->dataconnection = NULL;
                return (intval($this->reply()) == 226);
            } elseif(in_array($replyCode, Array(425, 426)) && $this->passive()) return $this->storeunique($fileordata, $path);
            $this->abort();
        }
        return false;
    }

    /**
     * public function retrieve
     * Get a file from FTP-server.
     *
     * @param    string    $path        The path you want to retrieve.
     * @param    string    $file        The file in which the file shall be fetched
     * @param    int        $restore    Position from 
     * @return    mixed                If $file is given: true on succes, false otherwise. Otherwise, datastring on succes NULL on failure.
     */
    public function retrieve($path, $file = false, $restore = false){
        $replyCode = 425;
        if(!is_numeric($restore) || ($this->file_exists($path) && (!is_numeric($restore) || (intval($this->command('REST ' . intval($restore))) == 350)))){
            if($this->dataconnection && $this->type('I') && is_string($path) && in_array(($replyCode = intval($this->command('RETR ' . $path))), Array(150, 125))){
                if(is_string($file)) $fp = fopen($file, 'wb');
                $reply = '';
                while(true){
                    if(is_string($replypart = fgets($this->dataconnection, 256))){
                        if(isset($fp) && ($reply = true)) fwrite($fp, $replypart);
                        else $reply .= $replypart;
                    }
                    if(!is_string($replypart)){
                        @fclose($this->dataconnection);
                        $this->dataconnection = NULL;
                        if(intval($this->reply()) == 226){
                            if(is_string($reply)) return $reply;
                            else return((!isset($fp) || @fclose($fp)) && $reply);
                        }
                    }
                }
            } elseif(in_array($replyCode, Array(425, 426)) && $this->passive()) return $this->retrieve($path, $file);
            $this->abort();
        }
        return NULL;
    }

    /**
     * public function store
     * Store a file on the FTP-server.
     *
     * @param    string    $remotefile    Path to the new file.
     * @param    string    $fileordata Path to file on current server or filedata.
     * @param    int        $restore    Restorepoint, remotefile will be cut off at that point and data will be append.
     * @return    boolean                True on succes, false otherwise.
     */
    public function store($remotefile, $fileordata, $restore = false){
        $replyCode = 425;
        if(is_string($remotefile) && is_string($fileordata)){
            if($this->dataconnection && $this->type('I') && (!is_numeric($restore) || (intval($this->command('REST ' . ($restore = intval($restore)))) == 350)) && in_array(intval($this->command('ALLO ' . (is_file($fileordata)? (filesize($fileordata) - (is_int($restore)? $restore : 0)) : strlen($fileordata)))), Array(200, 202)) && in_array(($replyCode = intval($this->command('STOR ' . $remotefile))), Array(150, 125))){
                if(!is_file($fileordata)) fwrite($this->dataconnection, $fileordata);
                elseif(is_file($fileordata) && ($fp = fopen($fileordata, 'rb')) && (!is_int($restore) || is_int(@fseek($fp, $restore)))) while(is_string($filepart = @fgets($fp))) fwrite($this->dataconnection, $filepart);
                elseif($this->abort()) return false;
                $this->abort();
                return (intval($this->reply()) == 226);
            }
            elseif(in_array($replyCode, Array(425, 426)) && $this->passive()) return $this->store($remotefile, $fileordata, $restore);
            $this->abort();
        }
        return false;
    }

    /**
     * public function append
     * Append file or filedata to an existed file.
     *
     * @param    string    $file
     * @param    string    $fileordata
     * @return    boolean                True on succes, false otherwise.
     */
    public function append($file, $fileordata){
        if(is_string($file) && is_string($fileordata)){
            $replyCode = 425;
            if($this->dataconnection && $this->type('I') && (intval($this->command('ALLO ' . (is_file($fileordata)? filesize($fileordata) : strlen($fileordata))))) && in_array(($replyCode = intval($this->command('APPE ' . $file))), Array(125, 150))){
                if(!is_file($fileordata))
                fwrite($this->dataconnection, $fileordata);
                elseif($fp = @fopen($fileordata, 'rb')) while(is_string($filepart = @fgets($fp))) fwrite($this->dataconnection, $filepart);
                elseif($this->abort()) return false;
                @fclose($this->dataconnection);
                $this->dataconnection = NULL;
                return (intval($this->reply()) == 226);
            }
            elseif(in_array($replyCode, Array(425, 426)) && $this->passive())
            return $this->append($file, $fileordata);
            $this->abort();
        }
        return false;
    }

    /**
     * public function passive
     * Create passive dataconnection.
     *
     * @return    boolean    True on succes, false otherwise.
     */
    public function passive(){
        if($this->dataconnection) $this->abort();
        if((intval($reply = $this->command('PASV')) == 227) && is_int($spos = strpos($reply, '(')) && is_int($epos = strpos($reply, ')', $spos))){
            $ipparts = explode(',', substr($reply, ($spos + 1), ($epos - $spos - 1)));
            if(count($ipparts) == 6){
                $host = '';
                $count = -1;
                while(++$count < 4){
                    if(is_numeric($ipparts[$count])) $host .= (($host == '')? '' : '.') . intval($ipparts[$count]);
                    else return false;
                }
                $port = ((intval($ipparts[4]) << 8) | intval($ipparts[5]));
                if($this->dataconnection = @fsockopen($host, $port, $errno, $errstr, 30)) return true;
            }
        }
        return false;
    }

    /**
     * public function dataconnection
     * Set type of dataconnection: A = ASCII, I = Octets.
     * 
     * @param    string    $type
     * @return    boolean            True on succes, false otherwise.
     */
    public function type($type){
        return (is_string($type) && (intval($this->command('TYPE ' . $type)) == 200));
    }

    /**
     * public function fileList
     * Get fileList of $path or current path if $path is not given.
     *
     * @param    string    $path
     * @param    boolean    $raw    Indicates wheter data has to returned as it is, without parsing.
     * @return    mixed            If $raw: String on succes, NULL on failure. Otherwise: Array on succes, NULL on failure.
     */
    public function fileList($path = false, $raw = false){
       $replyCode = 425;
        if(!is_string($path)) $raw = $path;
        if($this->dataconnection && $this->type('A') && (($mlsd = in_array(intval($this->command('MLSD ' . (is_string($path)? ' ' . $path : ''))), Array(150, 125))) || in_array(intval($this->command('LIST -a' . (is_string($path)? ' ' . $path : ''))), Array(150, 125)))){
            $records = '';
            while(true){
                if(is_string($replypart = fgets($this->dataconnection, 512))) $records .= $replypart;
                else {
                    @fclose($this->dataconnection);
                    $records = preg_split('#\r\n+#', $records, -1, PREG_SPLIT_NO_EMPTY);
                    $this->dataconnection = NULL;
                    if(intval($this->reply()) == 226){
                        if($raw) return implode(chr(0xD).chr(0xA), $records);
                        $files = Array();
                        if($mlsd){
                            foreach($records as $record){
                                if(!is_int($strpos = strpos($record, '; '))) $strpos = -1;
                                $files[($index = count($files))] = Array('name' => substr($record, ($strpos + 2)));
                                $opts = explode(';', rtrim(substr($record, 0, ++$strpos), chr(0).chr(9).chr(0x20).';'));
                                foreach($opts as $opt){
                                    if(is_int($strpos = strpos($opt, '='))){
                                        $optvalue = substr($opt, ($strpos + 1));
                                        switch($optname = strtolower(substr($opt, 0, $strpos))){
                                            case 'type':
                                                $files[$index]['type'] = (($optvalue == 'file')? 'F' : 'D');
                                            break;
                                            case 'size':
                                                $files[$index]['size'] = intval($optvalue);
                                            break;
                                            case 'modify':
                                            case 'create':
                                                $files[$index][$optname] = mktime(intval(substr($optvalue, -6, 2)), intval(substr($optvalue, -4, 2)), intval(substr($optvalue, -2)), intval(substr($optvalue, -10, 2)), intval(substr($optvalue, -8, 2)), intval(substr($optvalue, 0, (strlen($optvalue) - 10))));
                                            break;
                                            default:
                                                $files[$index][$optname] = $optvalue;
                                        }
                                    }
                                }
                            }
                        } else{
                            $systype = $this->systype();
                            if(preg_match('/(LI|U)NIX/i', $systype)){
                                while(is_string($record = current($records))){
                                    next($records);
                                    $fields = preg_split("/\s+/", $record);
                                    if(count($fields) > 8){
                                        $files[($index = count($files))] = Array('type' => ((($type = substr($fields[0], 0, 1)) == '-')? 'F' : strtoupper($type)), 'inode' => intval($fields[1]), 'perms' => 0, 'owner' => $fields[2], 'group' => $fields[3], 'size' => intval($fields[4]), 'name' => $fields[8]);
                                        $perms = substr($fields[0], 1);
                                        if(isset($fields[10])) $files[$index]['link'] = $fields[10];
                                        $count = -1;
                                        while(strlen($perms) > ++$count) $files[$index]['perms'] = ((($files[$index]['perms'] << 1) | ((int) (substr($perms, $count, 1) != '-'))));
                                    }
                                }
                            }else if(preg_match('/WIN/i', $systype)){
                                while(is_string($record = current($records))){
                                    next($records);
                                    if(strlen($record) > 40){
                                        $date = trim(substr($record, 0, 9));
                                        $time = trim(substr($record, 10, 7));
                                        $mtime = mktime((intval(substr($time, 0, 2)) + ((strtoupper(substr($time, 5, 2)) == 'PM')? 12 : 0)), intval(substr($time, 3, 2)), 0, intval(is_int($slashpos = strpos($date, '/'))? substr($date, 3, 2) : substr($date, 0, 2)), intval(is_int($slashpos)? substr($date, 0, 2) : substr($date, 3, 2)), ((($year = (2000 + intval(substr($date, 6, 2)))) > intval(date('Y')))? ($year - 100) : $year));
                                        $size = trim(substr($record, 18, 20));
                                        $files[] = Array('type' => (!is_numeric($size)? 'D' : 'F'), 'size' => (is_numeric($size)? intval($size) : 0), 'name' => substr($record, 39), 'modify' => $mtime);
                                    }
                                }
                            }
                        }
                        return $files;
                    }
                    break;
                }
            }
        } elseif(in_array($replyCode, Array(425, 426)) && $this->passive()) return $this->fileList($path, $raw);
        $this->abort();
        return NULL;
    }

    /**
     * public function namelist
     * Get list of filenames of $path or current directory.
     *
     * @param    string    $path
     * @return    Array            Array on succes, NULL on failure.
     */
    public function nameList($path = false){
        $replyCode = 425;
        if($this->dataconnection && $this->type('A') && in_array(($replyCode = intval($this->command('NLST' . (is_string($path)? ' ' . $path : '')))), Array(150, 125))){
            $namelist = Array();
            while(true){
                if(is_string($replypart = fgets($this->dataconnection, 128))) $namelist[] = rtrim($replypart);
                else {
                    @fclose($this->dataconnection);
                    $this->dataconnection = NULL;
                    if(intval($this->reply()) == 226) return $namelist;
                }
            }
        } else if(in_array($replyCode, Array(425, 426)) && $this->passive()) return $this->namelist($path);
        $this->abort();
        return NULL;
    }

    /**
     * public function  quit
     * Log out
     *
     * @return    boolean    True on succes, false otherwise.
     */
    public function quit(){
        if($this->dataconnection && @fclose($this->dataconnection)) $this->reply(false);
        return ($this->command('REIN') && (intval($this->command('QUIT')) == 221) && @fclose($this->connection));
    }
}

$ftp = new FTPSocket();
if($ftp->connect('host', 'user', 'pass')){
    var_dump($ftp->fileList()); # Array
    var_dump($ftp->mkdir('directory')); # true
    var_dump($ftp->file_exists('directory')); # true
    var_dump($ftp->cwdir('directory')); # true
    var_dump($ftp->cdup()); # true
    var_dump($ftp->rmdir('directory')); # true
    var_dump($ftp->file_exists('directory')); # false
    var_dump($ftp->features()); # Array
    var_dump($ftp->systype()); # String
    var_dump($ftp->pwdir()); # string '/'.
    var_dump($ftp->namelist()); # Array
    var_dump($ftp->quit()); # true
}

?>

Commentaar

07-04-2010 19:30

Geinig... simpele protocol wrapper... (it's done before.. ;-))

Niet om te mierenneuken.. of ja eigenlijk toch wel;

Waarom geen optionele manier om in de construct al direct te connecten (__construct())?

Waarom wel fileList()
Maar niet fileExists()

Je kunt geen class maken voor zowel PHP4 als PHP5, je geeft zelf al aan dat dat wijzigingen aan de source vergt... oftwel de class ansicht is niet onder PHP4 te gebruiken

Zeker als het gaat om major versie verschillen.. kies je of 4 of 5, met de voorkeur voor 5.

1
2
3
Post hier de source-code van je script. Alle informatie tussen <? ... ?> en <?php ... ?> zal automatisch worden getoond in color-coding. 

Let op! Het is niet de bedoeling om hier een link naar je website te plaatsen. Post hier gewoon de code, veel simpeler, sneller en meer kans dat het blijft staan.
07-04-2010 21:08

Als je even gekeken had, dan had je kunnen zien dat het script al twee jaar oud is (ruim). En ja, het is dus al eens eerder gedaan.

>>>>
Je kunt geen class maken voor zowel PHP4 als PHP5, je geeft zelf al aan dat dat wijzigingen aan de source vergt...
<<<<
Kan wel, maar dan moet je hem in PHP 4 schrijven. Hij was in eerste instantie geschreven voor PHP 4. En gezien ik het script zelf eigenlijk zelden gebruik, heb ik hem niet volledig omgeschreven naar PHP 5 (wat mijns inziens nu ook nog niet de bedoeling is, gezien nog veel mensen PHP 4 gebruiken en in PHP 5 de ftp-functies al een stuk meer gebruikt worden).

>>>>
oftwel de class ansicht is niet onder PHP4 te gebruiken
<<<<
Als het enkel om de keywords private, public en protected gaat, noem ik hem uitwisselbaar. Je hoeft zelfs niet na te denken bij het omschrijven. Gewoon search-replace...

>>>>
public function file_exists($path){
<<<<
Inderdaad een inconsistent gebruik van naamgeving. Denk dat ik de schrijfwijze van PHP aan heb geprobeerd te houden.

>>>>
Waarom geen optionele manier om in de construct al direct te connecten (__construct())?
<<<<
Omdat ik dan niet in een IF kan controleren of het connecten gelukt is. Je kunt namelijk niet teruggeven of het connecten gelukt is. Daarnaast moet je op die manier een extra functie voor status o.i.d. bij gaan houden. Daarnaast zit je dan met de verschil in constructornaam in PHP 4 vs. 5. Verder is het vrij ongebruikelijk in protocol wrappers om in de constructor al gelijk de connectie op te zetten.

>>>>
Niet om te mierenneuken..
<<<<
Zo ervaar ik het wel en beetje ja, goed dat je het zelf aangeeft :)

1
2
3
Post hier de source-code van je script. Alle informatie tussen <? ... ?> en <?php ... ?> zal automatisch worden getoond in color-coding. 

Let op! Het is niet de bedoeling om hier een link naar je website te plaatsen. Post hier gewoon de code, veel simpeler, sneller en meer kans dat het blijft staan.
08-04-2010 17:55

My bad.. heb idd niet gezien dat het 2 jaar oud is.. Je kunt je afvragen of iets wat 2 jaar oud is wel relevant genoeg is om in diezelfde staat op phpfreakz te plaatsen.

Domweg een string replace doen op "keywords" garandeerd geen werkende class... en is normaliter ook niet "the way to go"
$var = 'public'; hoeft niet specifiek gereplaced te worden voor PHP4

Waarom zou je persee met een if willen opvangen op de connectie gelukt is?
Je kunt toch (optioneel) connecten in de construct, een exceptie throwen als het mislukt.. en de class initialiseren in een try/catch..

> "Daarnaast zit je dan met de verschil in constructornaam in PHP 4 vs. 5."
En daarom maak je dus zowel een versie voor PHP4 als PHP5, je kunt het namelijk niet in 1 class houden

> "Verder is het vrij ongebruikelijk in protocol wrappers om in de constructor al gelijk de connectie op te zetten."
Valt wel mee hoor.. je moet het wel optioneel houden natuurlijk.

1
2
3
Post hier de source-code van je script. Alle informatie tussen <? ... ?> en <?php ... ?> zal automatisch worden getoond in color-coding. 

Let op! Het is niet de bedoeling om hier een link naar je website te plaatsen. Post hier gewoon de code, veel simpeler, sneller en meer kans dat het blijft staan.
12-04-2010 09:59

>>>>
Domweg een string replace doen op "keywords" garandeerd geen werkende class... en is normaliter ook niet "the way to go"
$var = 'public'; hoeft niet specifiek gereplaced te worden voor PHP4
<<<<
Voor deze class werkt het. Daarnaast heb je ook IDE's waar je specifiek kunt aangeven of enkel gezocht moet worden naar functienamen, constanten, keywords, e.d.

>>>>
Waarom zou je persee met een if willen opvangen op de connectie gelukt is?
Je kunt toch (optioneel) connecten in de construct, een exceptie throwen als het mislukt.. en de class initialiseren in een try/catch..
<<<<
Graag vijzel ik even je kennis rondom PHP en de history daarvan op. In PHP 4 was try-catch-finally nog niet in the picture. M.a.w.: houdt het graag binnen de mogelijkheden waarin het script destijds geschreven is. Voor het heden is het de vraag of de ftp-functies niet hetzelfde doen als mijn script.

>>>>
En daarom maak je dus zowel een versie voor PHP4 als PHP5, je kunt het namelijk niet in 1 class houden
<<<<
Gezien het enkel verschil maakt tussen de keywords public, protected en private denk ik daar zelfs niet over na. Zeker niet als ik het script zelf nog maar zelden gebruik en het naar mijn mening voldoet zoals het nu geschreven is.

>>>>
Valt wel mee hoor.. je moet het wel optioneel houden natuurlijk.
<<<<
Ah, valt wel mee... Klinkt alsof jij dagelijks protocol-wrappers schrijft. Zou jij mij even een protocol-wrapper willen aangeven die op normale kwaliteit geschreven, redelijk veel gebruikt wordt en die in de constructor gelijk connect?

Maar als je er zo aan ergert, mag je wat mij betreft het hele script herschrijven. Met alle plezier post ik het daarna wel even voor je in.

Misschien nog een specifiek vraagje van mijn kant. Waarom dit commentaar? Is dit een typisch voorbeeld van het zijken om het zijken?

1
2
3
Post hier de source-code van je script. Alle informatie tussen <? ... ?> en <?php ... ?> zal automatisch worden getoond in color-coding. 

Let op! Het is niet de bedoeling om hier een link naar je website te plaatsen. Post hier gewoon de code, veel simpeler, sneller en meer kans dat het blijft staan.
Inloggen wachtwoord vergeten? Aanmelden