: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
function rawlist($pathname="", $arg="") {
return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "LIST", "rawlist");
function nlist($pathname="", $arg="") {
return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "NLST", "nlist");
function is_exists($pathname) {
return $this->file_exists($pathname);
function file_exists($pathname) {
if(!$this->_exec("RNFR ".$pathname, "rename")) $exists=FALSE;
if(!$this->_checkCode()) $exists=FALSE;
if($exists) $this->SendMSG("Remote file ".$pathname." exists");
else $this->SendMSG("Remote file ".$pathname." does not exist");
function fget($fp, $remotefile, $rest=0) {
if($this->_can_restore and $rest!=0) fseek($fp, $rest);
$pi=pathinfo($remotefile);
if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
if(!$this->_data_prepare($mode)) {
if($this->_can_restore and $rest!=0) $this->restore($rest);
if(!$this->_exec("RETR ".$remotefile, "get")) {
if(!$this->_checkCode()) {
$out=$this->_data_read($mode, $fp);
if(!$this->_readmsg()) return FALSE;
if(!$this->_checkCode()) return FALSE;
function get($remotefile, $localfile=NULL, $rest=0) {
if(is_null($localfile)) $localfile=$remotefile;
if (@file_exists($localfile)) $this->SendMSG("Warning : local file will be overwritten");
$fp = @fopen($localfile, "w");
$this->PushError("get","cannot open local file", "Cannot create \"".$localfile."\"");
if($this->_can_restore and $rest!=0) fseek($fp, $rest);
$pi=pathinfo($remotefile);
if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
if(!$this->_data_prepare($mode)) {
if($this->_can_restore and $rest!=0) $this->restore($rest);
if(!$this->_exec("RETR ".$remotefile, "get")) {
if(!$this->_checkCode()) {
$out=$this->_data_read($mode, $fp);
if(!$this->_readmsg()) return FALSE;
if(!$this->_checkCode()) return FALSE;
function fput($remotefile, $fp, $rest=0) {
if($this->_can_restore and $rest!=0) fseek($fp, $rest);
$pi=pathinfo($remotefile);
if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
if(!$this->_data_prepare($mode)) {
if($this->_can_restore and $rest!=0) $this->restore($rest);
if(!$this->_exec("STOR ".$remotefile, "put")) {
if(!$this->_checkCode()) {
$ret=$this->_data_write($mode, $fp);
if(!$this->_readmsg()) return FALSE;
if(!$this->_checkCode()) return FALSE;
function put($localfile, $remotefile=NULL, $rest=0) {
if(is_null($remotefile)) $remotefile=$localfile;
if (!file_exists($localfile)) {
$this->PushError("put","cannot open local file", "No such file or directory \"".$localfile."\"");
$fp = @fopen($localfile, "r");
$this->PushError("put","cannot open local file", "Cannot read file \"".$localfile."\"");
if($this->_can_restore and $rest!=0) fseek($fp, $rest);
$pi=pathinfo($localfile);
if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
if(!$this->_data_prepare($mode)) {
if($this->_can_restore and $rest!=0) $this->restore($rest);
if(!$this->_exec("STOR ".$remotefile, "put")) {
if(!$this->_checkCode()) {
$ret=$this->_data_write($mode, $fp);
if(!$this->_readmsg()) return FALSE;
if(!$this->_checkCode()) return FALSE;
function mput($local=".", $remote=NULL, $continious=false) {
if(!@file_exists($local)) {
$this->PushError("mput","cannot open local folder", "Cannot stat folder \"".$local."\"");
if(!is_dir($local)) return $this->put($local, $remote);
if(empty($remote)) $remote=".";
elseif(!$this->file_exists($remote) and !$this->mkdir($remote)) return FALSE;
if($handle = opendir($local)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") $list[]=$file;
$this->PushError("mput","cannot open local folder", "Cannot read folder \"".$local."\"");
if(empty($list)) return TRUE;
if(is_dir($local."/".$el)) $t=$this->mput($local."/".$el, $remote."/".$el);
else $t=$this->put($local."/".$el, $remote."/".$el);
function mget($remote, $local=".", $continious=false) {
$list=$this->rawlist($remote, "-lA");
$this->PushError("mget","cannot read remote folder list", "Cannot read remote folder \"".$remote."\" contents");
if(empty($list)) return true;
if(!@file_exists($local)) {
$this->PushError("mget","cannot create local folder", "Cannot create folder \"".$local."\"");
foreach($list as $k=>$v) {
$list[$k]=$this->parselisting($v);
if( ! $list[$k] or $list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]);
if(!$this->mget($remote."/".$el["name"], $local."/".$el["name"], $continious)) {
$this->PushError("mget", "cannot copy folder", "Cannot copy remote folder \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\"");
if(!$this->get($remote."/".$el["name"], $local."/".$el["name"])) {
$this->PushError("mget", "cannot copy file", "Cannot copy remote file \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\"");
@chmod($local."/".$el["name"], $el["perms"]);
$t=strtotime($el["date"]);
if($t!==-1 and $t!==false) @touch($local."/".$el["name"], $t);
function mdel($remote, $continious=false) {
$list=$this->rawlist($remote, "-la");
$this->PushError("mdel","cannot read remote folder list", "Cannot read remote folder \"".$remote."\" contents");
foreach($list as $k=>$v) {
$list[$k]=$this->parselisting($v);
if( ! $list[$k] or $list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]);
if(!$this->mdel($remote."/".$el["name"], $continious)) {
if (!$this->delete($remote."/".$el["name"])) {
$this->PushError("mdel", "cannot delete file", "Cannot delete remote file \"".$remote."/".$el["name"]."\"");
if(!$this->rmdir($remote)) {
$this->PushError("mdel", "cannot delete folder", "Cannot delete remote folder \"".$remote."/".$el["name"]."\"");
function mmkdir($dir, $mode = 0777) {
if(empty($dir)) return FALSE;
if($this->is_exists($dir) or $dir == "/" ) return TRUE;
if(!$this->mmkdir(dirname($dir), $mode)) return false;
$r=$this->mkdir($dir, $mode);
$this->chmod($dir,$mode);
function glob($pattern, $handle=NULL) {
if(PHP_OS=='WIN32') $slash='\\';
$lastpos=strrpos($pattern,$slash);
if(!($lastpos===false)) {
$path=substr($pattern,0,-$lastpos-1);
$pattern=substr($pattern,$lastpos);
if(is_array($handle) and !empty($handle)) {
foreach($handle as $dir) {
if($this->glob_pattern_match($pattern,$dir))
if($handle===false) return false;
while($dir=readdir($handle)) {
if($this->glob_pattern_match($pattern,$dir))
if(is_array($output)) return $output;
function glob_pattern_match($pattern,$subject) {
$chunks=explode(';',$pattern);
foreach($chunks as $pattern) {
$escape=array('$','^','.','{','}','(',')','[',']','|');
while(str_contains($pattern,'**'))
$pattern=str_replace('**','*',$pattern);
foreach($escape as $probe)
$pattern=str_replace($probe,"\\$probe",$pattern);
$pattern=str_replace('?*','*',
str_replace('?','.{1,1}',$pattern))));
if(count($out)==1) return($this->glob_regexp("^$out[0]$",$subject));
// TODO: This should probably be glob_regexp(), but needs tests.
if($this->my_regexp("^$tester$",$subject)) return true;
function glob_regexp($pattern,$subject) {
$sensitive=(PHP_OS!='WIN32');
preg_match( '/' . preg_quote( $pattern, '/' ) . '/', $subject ) :
preg_match( '/' . preg_quote( $pattern, '/' ) . '/i', $subject )
function dirlist($remote) {
$list=$this->rawlist($remote, "-la");
$this->PushError("dirlist","cannot read remote folder list", "Cannot read remote folder \"".$remote."\" contents");
foreach($list as $k=>$v) {
$entry=$this->parselisting($v);
if($entry["name"]=="." or $entry["name"]=="..")
$dirlist[$entry['name']] = $entry;
// <!-- --------------------------------------------------------------------------------------- -->
// <!-- Private functions -->
// <!-- --------------------------------------------------------------------------------------- -->
return ($this->_code<400 and $this->_code>0);
function _list($arg="", $cmd="LIST", $fnction="_list") {
if(!$this->_data_prepare()) return false;
if(!$this->_exec($cmd.$arg, $fnction)) {
if(!$this->_checkCode()) {
$out=$this->_data_read();
if(!$this->_readmsg()) return FALSE;
if(!$this->_checkCode()) return FALSE;
if($out === FALSE ) return FALSE;
$out=preg_split("/[".CRLF."]+/", $out, -1, PREG_SPLIT_NO_EMPTY);
// $this->SendMSG(implode($this->_eol_code[$this->OS_local], $out));
// <!-- --------------------------------------------------------------------------------------- -->
// <!-- Partie : gestion des erreurs -->
// <!-- --------------------------------------------------------------------------------------- -->
// Gnre une erreur pour traitement externe la classe
function PushError($fctname,$msg,$desc=false){
$error['fctname']=$fctname;
if($desc) $tmp=' ('.$desc.')'; else $tmp='';
$this->SendMSG($fctname.': '.$msg.$tmp);
return(array_push($this->_error_array,$error));
// Rcupre une erreur externe
if(count($this->_error_array)) return(array_pop($this->_error_array));
$mod_sockets = extension_loaded( 'sockets' );
if ( ! $mod_sockets && function_exists( 'dl' ) && is_callable( 'dl' ) ) {
$prefix = ( PHP_SHLIB_SUFFIX == 'dll' ) ? 'php_' : '';
@dl( $prefix . 'sockets.' . PHP_SHLIB_SUFFIX ); // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.dlDeprecated
$mod_sockets = extension_loaded( 'sockets' );
require_once __DIR__ . "/class-ftp-" . ( $mod_sockets ? "sockets" : "pure" ) . ".php";
class ftp extends ftp_sockets {}
class ftp extends ftp_pure {}