目次
PHPを使って効率的で安全なftpサーバーを実装する(2)、PHPでftpサーバーを実装する
1. ユーザークラス CUser を実装します。
2. 共有メモリ操作クラス
3.内置型Webサービス
ホームページ バックエンド開発 PHPチュートリアル PHP を使用して効率的で安全な FTP サーバーを実装する (2)、PHP を使用して FTP サーバーを実装する_PHP チュートリアル

PHP を使用して効率的で安全な FTP サーバーを実装する (2)、PHP を使用して FTP サーバーを実装する_PHP チュートリアル

Jul 12, 2016 am 09:02 AM
データベースに接続する

PHPを使って効率的で安全なftpサーバーを実装する(2)、PHPでftpサーバーを実装する

前回の記事からの続きです。

1. ユーザークラス CUser を実装します。

ユーザーはテキスト形式で保存され、ユーザー配列はjsonエンコードされます。

リーリー

フォルダーとファイルの許可手順:

リーリー

実装コードは次のとおりです:

PHP を使用して効率的で安全な FTP サーバーを実装する (2)、PHP を使用して FTP サーバーを実装する_PHP チュートリアルクラスユーザー{ const I = 1; //継承 const FD = 2; //フォルダー削除 const FN = 4; //フォルダーの名前を変更 const FC = 8; //フォルダー作成 const FL = 16; //フォルダーリスト const D = 32; //ファイル削除 const N = 64; //ファイル名変更 const A = 128; //ファイル追加 const W = 256; //ファイル書き込み(アップロード) const R = 512; //ファイル読み取り(ダウンロード) プライベート $hash_salt = ''; プライベート $user_file; プライベート $group_file; プライベート $users = array(); プライベート $groups = array(); プライベート $file_hash = ''; パブリック 関数 __construct(){ $this->user_file = BASE_PATH.'/conf/users'; $this->group_file = BASE_PATH.'/conf/groups'; $this->reload(); } /** * 戻り权制限表达式 * @param int $access * @戻り文字列 */ パブリック 静的 関数 AC($access){ $str = ''; $char = array('R','W','A','N','D','L','C','N','D','I' ); for($i = 0; $i $i++){ if($access & pow(2,9-$i))$str.= $char[$i];else $str.= 「-」; } リターン $str; } /** * 追加用户データ */ パブリック 関数 reload(){ $user_file_hash = md5_file($this->user_file); $group_file_hash = md5_file($this->group_file); if($this->file_hash != md5($user_file_hash.$group_file_hash)){ if(($user = file_get_contents($this->user_file)) !== false){ $this->users = json_decode($user,true); if($this->ユーザー){ //folder排序 foreach ($this->ユーザー as $user=>$profile){ if(isset($profile['フォルダ'])){ $this->users[$user]['folder'] = $this->sortFolder($profile['folder']); } } } }if(($group = file_get_contents($this->group_file)) !== false){ $this->groups = json_decode($group,true); if($this->グループ){ //folder排序 foreach ($this->グループ as $group=>$profile){ if(isset($profile['フォルダ'])){ $this->groups[$group]['フォルダー'] = $this->sortFolder($profile['フォルダー']); } } } } $this->file_hash = md5($user_file_hash.$group_file_hash); } } /** *对フォルダ行排序 * @return 配列 */ プライベート 関数 sortFolder($folder){ uasort($フォルダー, 関数($a,$b){ return strnatcmp($a['path'], $b['path']); }); $result = array(); foreach ($フォルダー as $v){ $結果[] = $v; } リターン $結果; } /** *保存用户データ */ パブリック 関数 save(){ file_put_contents($this->user_file, json_encode($this->users),LOCK_EX); file_put_contents($this->グループファイル, json_encode($this->グループ),LOCK_EX); } /** * 添加用户 * @param 文字列 $user * @param 文字列 $pass * @param 文字列 $home * @param string $expired * @param boolean $active * @param 文字列 $group * @param string $description * @param string $email * @return ブール値 */ public function addUser($user,$pass,$home,$expired,$active=true,$group='',$description= '',$email = ''){ $user = strto lower($user); if(isset($this->users[$user]) || ($user)){ 戻る false; } $this->users[$user] = array( 'パス' => md5($user.$this->hash_salt.$pass), 'ホーム' => $ホーム、 '期限切れ' => $期限切れ、 'アクティブ' => $アクティブ、 'グループ' => $グループ、 '説明' => $説明、 '電子メール' => $メール ); 戻る 本当; } /** * 設置用户費 * @param 文字列 $user * @param 配列 $profile * @return ブール値 */ public function setUserProfile($user,$profile){ $user = strto lower($user); if(is_array($profile) && isset($this->users[$user])){ if(isset($profile['pass'])){ $profile['pass'] = md5($user.$this->hash_salt.$profile['pass']); }if(isset($profile['active'])){ if(!is_bool($profile['active'])){ $profile['active'] = $profile['active'] == 'true' ? :; } } $this->users[$user] = array_merge($this->users[$user],$profile); 戻る 本当; } 戻る false; } /** *获取用户资料 * @param 文字列 $user * @return multitype:|boolean */ パブリック 関数 getUserProfile($user){ $user = strto lower($user); if(isset($this->ユーザー[$user])){ return $this->users[$user]; } 戻る false; } /** *删除用户 * @param 文字列 $user * @return ブール値 */ パブリック 関数 delUser($user){ $user = strto lower($user); if(isset($this->ユーザー[$user])){ 設定解除($this->ユーザー[$user]); 戻る 本当; } 戻る false; } /** * 获取用户列表 * @return 配列 */ パブリック 関数 getUserList(){ $list = array(); if($this->ユーザー){ foreach ($this->ユーザー as $user=>$profile){ $list[] = $user; } } 並べ替え($リスト); 戻る $リスト; } /** * 添加組 * @param 文字列 $group * @param 文字列 $home * @return ブール値 */ パブリック 関数 addGroup($group,$home){ $group = strto lower($group); if(isset($this->グループ[$group])){ 戻る false; } $this->グループ[$グループ] = 配列( 'ホーム' => $ホーム ); 戻る 本当; } /** * 設置費 * @param 文字列 $group * @param 配列 $profile * @return ブール値 */ public function setGroupProfile($group,$profile){ $group = strto lower($group); if(is_array($profile) && isset($this->groups[$group])){ $this->グループ[$グループ] = array_merge($this->グループ[$グループ],$プロファイル); 戻る 本当; } 戻る false; } /** *获取组资料 * @param 文字列 $group * @return multitype:|boolean */ パブリック 関数 getGroupProfile($group){ $group = strto lower($group); if(isset($this->グループ[$group])){ 戻る $this->グループ[$グループ]; } 戻る false; }/** * グループの削除 * @param 文字列 $group * @return ブール値 */ パブリック 関数 delGroup($group){ $group = strto lower($group); if(isset($this->グループ[$group])){ 設定解除($this->グループ[$group]); foreach ($this->ユーザーas $user => $profile){ if($profile['グループ'] == $グループ) $this->ユーザー[$user]['グループ'] = ''; } 戻る 本当; } 戻る false; } /** * グループリストを取得する * @return 配列 */ パブリック 関数 getGroupList(){ $list = array(); if($this->グループ){ foreach ($this->グループas $group=>$profile){ $リスト[] = $グループ; } } 並べ替え($リスト); 戻る $リスト; } /** * グループユーザーリストの取得 * @param 文字列 $group * @return 配列 */ パブリック 関数 getUserListOfGroup($group){ $list = array(); if(isset($this->グループ[$グループ]) && $this->ユーザー){ foreach ($this->ユーザー as $user=>$profile){ if(isset($profile['グループ']) && $profile['グループ'] == $グループ){ $list[] = $user; } } } 並べ替え($リスト); 戻る $リスト; } /** * ユーザ認証 * @param 文字列 $user * @param 文字列 $pass * @パラメータ文字列$ip * @return ブール値 */ public function checkUser($user,$pass,$ip = ''){ $this->reload(); $user = strto lower($user); if(isset($this->ユーザー[$user])){ if($this->users[$user]['active'] && time() strtotime($this->users[$user) ][「期限切れ」]) && $this->users[$user]['pass'] == md5($user.$this->hash_salt.$pass)){ if(($ip)){ 戻る 本当; }{ //IP認証 return $this->checkIP($user, $ip); } }{ 戻る false; } } 戻る false; }/** * 基本認証 * @パラメータ文字列$base64 */ パブリック 関数 checkUserBasicAuth($base64){ $base64 = trim(str_replace('Basic ', '', $base64)); $str = base64_decode($base64); if($str !== false){ list($user,$pass) = explode(':', $str,2); $this->reload(); $user = strto lower($user); if(isset($this->ユーザー[$user])){ $group = $this->users[$user]['グループ']; if($group == 'admin' && $this->users[$user]['active'] && time() <= strtotime($this ->ユーザー[$user]['期限切れ']) && $this->users[$user]['pass'] == md5($user.$this->hash_salt.$pass)){ 戻る 本当; }{ 戻る false; } } } 戻る false; } /** * 用户登录ip验证 * @param 文字列 $user * @パラメータ文字列$ip * * ユーザの IP 制限は、承認グループの IP 制限に従います。* マッチングルール: * 1. グループ許可リストの照合を実行します。 * 2. 合格したかのように、グループ拒否リストのマッチングを実行します。 * 3. ユーザー権限の照合を実行します。 * 4. 合格した場合、ユーザー拒否マッチングを実行します。 * */ パブリック 関数 checkIP($user,$ip){ $pass = false; //最初にグループ認証を実行します $group = $this->users[$user]['グループ']; //グループでマッチングが可能です if(isset($this->グループ[$group]['ip']['allow'])){ foreach ($this->groups[$group]['ip']['allow'] as $addr){ $pattern = '/'.str_replace('*','d+',str_replace('.', '.', $addr)).'/'; if(preg_match($pattern, $ip) && !empty($addr)){ $pass = true; 休憩; } } } //許可されている場合は、マッチングを拒否します if($pass){ if(isset($this->グループ[$group]['ip']['deny'])){ foreach ($this->groups[$group]['ip']['deny'] as $addr){ $pattern = '/'.str_replace('*','d+',str_replace('.', '.', $addr)).'/'; if(preg_match($pattern, $ip) && !empty($addr)){ $pass = false; 休憩; } } } } if(isset($this->users[$user]['ip']['allow'])){ foreach ($this->users[$user]['ip']['allow'] as $addr){ $pattern = '/'.str_replace('*','d+',str_replace('.', '.', $addr)).'/'; if(preg_match($pattern, $ip) && !empty($addr)){ $pass = true; 休憩; } } } if($pass){ if(isset($this->users[$user]['ip']['deny'])){ foreach ($this->users[$user]['ip']['deny'] as $addr){ $pattern = '/'.str_replace('*','d+',str_replace('.', '.', $addr)).'/'; if(preg_match($pattern, $ip) && !empty($addr)){ $pass = false; 休憩; } } } } echo date('Y-m-d H:i:s')." [debug]tIP ACCESS:".' '.($pass?'true':'false')."n"; リターン $pass; } /** * ユーザーのホームディレクトリを取得します * @param 文字列 $user * @戻り文字列 */ パブリック 関数 getHomeDir($user){ $user = strto lower($user); $group = $this->users[$user]['グループ']; $dir = ''; if($グループ){ if(isset($this->グループ[$group]['home']))$dir = $this->グループ[$group][ 「家」]; }$dir = !empty($this->users[$user]['home'])?$this->users[$user]['home' ]:$ディレクトリ; return $dir; } //文件权限界判断 public function isReadable($user,$path){ $result = $this->getPathAccess($user, $path); if($result['isExactMatch']){ return $result['access'][0] == 'R'; }{ return $result['access'][0] == 'R' && $result['access'][9] == 'I'; } } public function isWritable($user,$path){ $result = $this->getPathAccess($user, $path); if($result['isExactMatch']){ return $result['access'][1] == 'W'; }{ return $result['access'][1] == 'W' && $result['access'][9] == 'I'; } } public function isAppendable($user,$path){ $result = $this->getPathAccess($user, $path); if($result['isExactMatch']){ return $result['access'][2] == 'A'; }{ return $result['access'][2] == 'A' && $result['access'][9] == 'I'; } } public function isRenamable($user,$path){ $result = $this->getPathAccess($user, $path); if($result['isExactMatch']){ return $result['access'][3] == 'N'; }{ return $result['access'][3] == 'N' && $result['access'][9] == 'I'; } } public function isDeletable($user,$path){ $result = $this->getPathAccess($user, $path); if($result['isExactMatch']){ return $result['access'][4] == 'D'; }{ return $result['access'][4] == 'D' && $result['access'][9] == 'I'; } } //目录权限界判断 public function isFolderListable($user,$path){ $result = $this->getPathAccess($user, $path); if($result['isExactMatch']){ return $result['access'][5] == 'L'; }{ return $result['access'][5] == 'L' && $result['access'][9] == 'I'; } } public function isFolderCreatable($user,$path){ $result = $this->getPathAccess($user, $path); if($result['isExactMatch']){ return $result['access'][6] == 'C'; }{ return $result['access'][6] == 'C' && $result['access'][9] == 'I'; } }public function isFolderRenamable($user,$path){ $result = $this->getPathAccess($user, $path); if($result['isExactMatch']){ return $result['access'][7] == 'N'; }{ return $result['access'][7] == 'N' && $result['access'][9] == 'I'; } } public function isFolderDeletable($user,$path){ $result = $this->getPathAccess($user, $path); if($result['isExactMatch']){ return $result['access'][8] == 'D'; }{ return $result['access'][8] == 'D' && $result['access'][9] == 'I'; } } /** *获取目录权制限 * @param 文字列 $user * @param 文字列 $path * @return 配列 * 最长路​​径適合を実行します * * 戻り: * 配列( * 'access'=>目前权制限 * ,'isExactMatch'=>否か精确適合 * * ); * *如果精确適合、则忽略継承。 * 否则应判断是否继承父目录的权限, * 权制限位表: * +---+---+---+---+---+---+---+---+---+---+ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | * +---+---+---+---+---+---+---+---+---+---+ * | R | W |あ | N | D | L | C | N | D |私 | * +---+---+---+---+---+---+---+---+---+---+ * | ファイル | フォルダ | * +-------------------+-------------------+ */ パブリック 関数 getPathAccess($user,$path){ $this->reload(); $user = strto lower($user); $group = $this->users[$user]['グループ']; //削除文書名 $path = str_replace(substr(strrchr($path, '/'),1),'',$path); $access = self::AC(0); $isExactMatch = false; if($グループ){ if(isset($this->グループ[$グループ]['フォルダー'])){ foreach ($this->groups[$group]['folder'] as $f){ //中文处理 $t_path = iconv('UTF-8','GB18030',$f['パス']); if(strpos($path, $t_path) === 0){ $access = $f['access']; $isExactMatch = ($path == $t_path?true:false); } } } } if(isset($this->users[$user]['folder'])){ foreach ($this->users[$user]['folder'] as $f){ //中文处理 $t_path = iconv('UTF-8','GB18030',$f['パス']); if(strpos($path, $t_path) === 0){ $access = $f['access']; $isExactMatch = ($path == $t_path?true:false); } } } echo date('Y-m-d H:i:s')." [debug]tACCESS:$access ".' '.($isExactMatch?'1':'0')." $pathn"; return array('access'=>$access,'isExactMatch'=>$isExactMatch); }/** * 追加在中用 * @param ShareMemory $shm * @param swoole_server $serv * @param 不明な $user * @param 不明 $fd * @param 不明な $ip * @return Ambigous > */ public function addOnline(ShareMemory $shm ,$serv,$user,$fd,$ip){ $shm_data = $shm->read(); if($shm_data !== false){ $shm_data['online'][$user.'-'.$fd] = array('ip'=>$ip,'time'=>time ()); $shm_data['last_login'][] = array('user' => $user,'ip'=>$ip,'time'=>time( )); //古いデータを削除 if(count($shm_data['last_login'])>30)array_shift($shm_data['last_login']); $list = array(); foreach ($shm_data['online'] as $k =>$v){ $arr = 爆発('-', $k); if($serv->connection_info($arr[1]) !== false){ $list[$k] = $v; } } $shm_data['オンライン'] = $list; $shm->write($shm_data); } 戻る $shm_data; } /** * 追加登陆失败记录 * @param ShareMemory $shm * @param 不明な $user * @param 不明な $ip * @return 曖昧な */ public function addAttempt(ShareMemory $shm ,$user,$ip){ $shm_data = $shm->read(); if($shm_data !== false){ if(isset($shm_data['login_attempt'][$ip.'||'.$user]['count'])){ $shm_data['login_attempt'][$ip.'||'.$user]['count'] += 1; }{ $shm_data['login_attempt'][$ip.'||'.$user]['count'] = 1; } $shm_data['login_attempt'][$ip.'||'.$user]['time'] = time(); //古いデータを削除 if(count($shm_data['login_attempt'])>30)array_shift($shm_data['login_attempt']); $shm->write($shm_data); } 戻る $shm_data; } /** * 密暗号错误上限 * @param 不明 $shm * @param 不明な $user * @param 不明な $ip * @return ブール値 */ public function isAttemptLimit(ShareMemory $shm,$user,$ip){ $shm_data = $shm->read(); if($shm_data !== false){ if(isset($shm_data['login_attempt'][$ip.'||'.$user]['count'])){ if($shm_data['login_attempt'][$ip.'||'.$user]['count'] > 10 && time() - $shm_data['login_attempt'][$ip.'||'.$user]['time'] < 600){ 戻る 本当; } } } 戻る false; }/** * ランダムキーを生成 * @param int $len * @return 曖昧な */ パブリック 静的 関数 genPassword($len){ $str = null; $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz@!#$%*+-"; $max = strlen($strPol)-1; for($i=0;$i<$len;$i++){ $str.=$strPol[rand(0,$max)];//rand($min,$max) は最小値と最大値の間の数値を生成します ランダムな整数 } リターン $str; } } コードを表示

2. 共有メモリ操作クラス

これは比較的簡単で、php の shmop 拡張機能を使用するだけです。

PHP を使用して効率的で安全な FTP サーバーを実装する (2)、PHP を使用して FTP サーバーを実装する_PHP チュートリアルクラス ShareMemory{ プライベート $mode = 0644; プライベート $shm_key; プライベート $shm_size; /** *构造関数数 */ パブリック 関数 __construct(){ $key = 'F'; $サイズ = 1024*1024; $this->shm_key = ftok(__FILE__,$key); $this->shm_size = $size + 1; } /** *读取内存数组 * @return 配列|ブール値 */ パブリック 関数 read(){ if(($shm_id = shmop_open($this->shm_key,'c',$this->モード,$this->shm_size)) !== false ){ $str = shmop_read($shm_id,1,$this->shm_size-1); shmop_close($shm_id); if(($i = strpos($str," ")) !== false)$str = substr($str,0,$i ); if($str){ return json_decode($str,true); }{ return array(); } } 戻る false; } /** * 写量组到内存 * @param 配列 $arr * @return int|boolean */ パブリック 関数 write($arr){ if(!is_array($arr))return false; $str = json_encode($arr)." "; if(strlen($str) > $this->shm_size) return false; if(($shm_id = shmop_open($this->shm_key,'c',$this->モード,$this->shm_size)) !== false ){ $count = shmop_write($shm_id,$str,1); shmop_close($shm_id); 戻る $count; } 戻る false; } /** * 删除内保存块、次回使用時に再新开辟内保存块 * @return ブール値 */ パブリック 関数 delete(){ if(($shm_id = shmop_open($this->shm_key,'c',$this->モード,$this->shm_size)) !== false ){ $result = shmop_delete($shm_id); shmop_close($shm_id); リターン $結果; } 戻る false; } } コードを表示

3.内置型Webサービス

これは主に ftp の http サーバー タイプに組み込まれており、機能が完璧ではなく、ftp の管理も実行できます。これは、apache などの他の http サーバーで実行される方法とは異なる可能性があることに注意してください。内に保管しております。

PHP を使用して効率的で安全な FTP サーバーを実装する (2)、PHP を使用して FTP サーバーを実装する_PHP チュートリアルクラス CWebServer{ 保護 $buffer_header = array(); 保護 $buffer_maxlen = 65535; //最大POSTサイズ const DATE_FORMAT_HTTP = 'D, d-M-Y H:i:s T'; const HTTP_EOF = "rnrn"; const HTTP_HEAD_MAXLEN = 8192; // http ヘッダーの最大長は 2k を超えてはなりません const HTTP_POST_MAXLEN = 1048576;//1m const ST_FINISH = 1; //完了、処理フローに入ります const ST_WAIT = 2 //データを待っています; const ST_ERROR = 3; //エラー、このパッケージを破棄します プライベート $requsts = array(); プライベート $config = array(); public function log($msg,$level = 'デバッグ'){ echo date('Y-m-d H:i:s').' ['.$level."]t" .$msg."n"; } public function __construct($config = array()){ $this->config = array( 'wwwroot' => __DIR__.'/wwwroot/', 'インデックス' => 'インデックス.php', 'path_deny' => 配列('/protected/'), ); } public function onReceive($serv,$fd,$data){ $ret = $this->checkData($fd, $data); スイッチ ($ret){ ケース self::ST_ERROR: $serv->close($fd); $this->cleanBuffer($fd); $this->log('受信エラー。'); 休憩; ケース self::ST_WAIT: $this->log('受信はお待ちください。'); 戻る; デフォルト: 休憩; } //完全なリクエストを開始します $request = $this->リクエスト[$fd]; $info = $serv->connection_info($fd); $request = $this->parseRequest($request); $request['remote_ip'] = $info['remote_ip']; $response = $this->onRequest($request); $output = $this->parseResponse($request,$response); $serv->send($fd,$output); if(isset($request['head']['Connection']) && strto lower($request['head']['Connection']) == 'close' ){ $serv->close($fd); } 設定解除($this->リクエスト[$fd]); $_REQUEST = $_SESSION = $_COOKIE = $_FILES = $_POST = $_SERVER = $_GET = array() ; }/** *处理请求 * @param 配列 $request * @return array $response * * $リクエスト=配列( * '時間'=> * 'head'=>配列( * 'メソッド'=> * 'パス'=> * 'プロトコル'=> * 'uri'=> * //その他の http ヘッダー * '..'=>値 *) * '本体'=> * 'get'=>(該当する場合) * 'post'=>(該当する場合) * 'cookie'=>(該当する場合) * * *) */ パブリック 関数 onRequest($request){ if($request['head']['path'][strlen($request['head']['path']) - 1] == '/'){ $request['head']['path'] .= $this->config['index']; } $response = $this->プロセス($request); リターン $レスポンス; } /** * 消去データ * @param 不明 $fd */ パブリック 関数 cleanBuffer($fd){ 設定解除($this->リクエスト[$fd]); 設定解除($this->buffer_header[$fd]); } /** * 检查データ * @param 不明 $fd * @param 不明な $data * @戻り文字列 */ パブリック 関数 checkData($fd,$data){ if(isset($this->buffer_header[$fd])){ $data = $this->buffer_header[$fd].$data; } $request = $this->checkHeader($fd, $data); //请求头错误 if($request === false){ $this->buffer_header[$fd] = $data; if(strlen($data) > self::HTTP_HEAD_MAXLEN){ return self::ST_ERROR; }{ return self::ST_WAIT; } } //投稿请求检查 if($request['head']['method'] == 'POST'){ return $this->checkPost($request); }{ return self::ST_FINISH; } } /** *检查请求头 * @param 不明 $fd * @param 不明な $data * @return ブール値|配列 */ public function checkHeader($fd, $data){ //新しい依頼 if(!isset($this->requsts[$fd])){ //http头结束符 $ret = strpos($data,self::HTTP_EOF); if($ret === false){ 戻る false; }{ $this->buffer_header[$fd] = ''; $request = array(); list($header,$request['body']) = explode(self::HTTP_EOF, $data,2); $request['head'] = $this->parseHeader($header); $this->リクエスト[$fd] = $リクエスト; if($request['head'] == false){ 戻る false; } } }{ //ポストデータマージ $request = $this->リクエスト[$fd]; $request['body'] .= $data; } 返却 $リクエスト; } /** * リクエストヘッダーを解析する * @param string $header * @return 配列 * 配列( * 'メソッド'=>, * 'uri'=> * 'プロトコル'=> * '名前'=>値,... * * * * } */ public function parseHeader($header){ $request = array(); $headlines = explode("rn", $header); list($request['メソッド'],$request['uri'],$request['プロトコル']) = explode(' ', $headlines[0] ,3); foreach ($見出し as $k=>$line){ $line = トリム($line); if($k && !($line) && strpos($line,':') !== false){ list($name,$value) = explode(':', $line,2); $request[trim($name)] = trim($value); } } 返却 $リクエスト; } /** ※投稿データが揃っているか確認してください * @param 不明な $request * @戻り文字列 */ パブリック 関数 checkPost($request){ if(isset($request['head']['Content-Length'])){ if(intval($request['head']['Content-Length']) > self::HTTP_POST_MAXLEN){ return self::ST_ERROR; } if(intval($request['head']['Content-Length']) > strlen($request['body'])){ return self::ST_WAIT; }{ return self::ST_FINISH; } } return self::ST_ERROR; } /** * リクエストを解析する * @param 不明な $request * @return 曖昧な */ パブリック 関数 parseRequest($request){ $request['time'] = time(); $url_info = parse_url($request['head']['uri']); $request['head']['path'] = $url_info['path']; if(isset($url_info['フラグメント']))$request['ヘッド']['フラグメント'] = $url_info['フラグメント']; if(isset($url_info['クエリ'])){ parse_str($url_info['query'],$request['get']); } //投稿本文を解析する if($request['head']['method'] == 'POST'){ //現在フォーム送信のみを処理しています if (isset($request['head']['Content-Type']) && substr($request['head']['Content-Type'], 0, 33 ) == 'application/x-www-form-urlencoded' || isset($request['head']['X-Request-With']) && $request['head']['X-Request-With'] == 'XMLHttpRequest' ){ parse_str($request['body'],$request['post']); } }//クッキーを解析する if(!($request['head']['Cookie'])){ $params = array(); $blocks = explode(";", $request['head']['Cookie']); foreach ($ブロック as $b){ $_r = 爆発("=, $b, 2); if(カウント($_r)==2){ リスト ($key, $value) = $_r; $params[trim($key)] = trim($value, "rn t""); }{ $params[$_r[0]] = ''; } } $request['cookie'] = $params; } 返却 $リクエスト; } public function parseResponse($request,$response){ if(!isset($response['head']['Date'])){ $response['head']['Date'] = gmdate("D, d M Y H:i:s T"); } if(!isset($response['head']['Content-Type'])){ $response['head']['Content-Type'] = 'text/html;charset=utf-8'; } if(!isset($response['head']['Content-Length'])){ $response['head']['Content-Length'] = strlen($response['body']); } if(!isset($response['head']['Connection'])){ if(isset($request['head']['Connection']) && strto lower($request['head']['Connection']) == 'キープアライブ'){ $response['head']['Connection'] = 'キープアライブ'; }{ $response['head']['Connection'] = 'close'; } } $response['head']['Server'] = CFtpServer::$software.'/'.CFtpServer::VERSION; $out = ''; if(isset($response['head']['Status'])){ $out .= 'HTTP/1.1 '.$response['head']['Status']."rn"; unset($response['head']['Status']); }{ $out .= "HTTP/1.1 200 OKrn"; } //ヘッダー foreach($response['head'] as $k=>$v){ $out .= $k.': '.$v."rn"; } //クッキー if($_COOKIE){ $arr = array(); foreach ($_COOKIE as $k => $v){ $arr[] = $k.'='.$v; } $out .= 'Set-Cookie: '.implode(';', $arr)."rn"; } //終了 $out .= "rn"; $out .= $response['body']; 返品 $out
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHP を使用してデータベース内の最初の数レコードを読み取るにはどうすればよいですか? PHP を使用してデータベース内の最初の数レコードを読み取るにはどうすればよいですか? Mar 22, 2024 am 10:03 AM

PHP を使用してデータベース内の最初の数レコードを読み取るにはどうすればよいですか? Web アプリケーションを開発するとき、多くの場合、データベースからデータを読み取り、ユーザーに表示する必要があります。場合によっては、コンテンツ全体ではなく、データベース内の最初の数レコードだけを表示する必要があることがあります。この記事では、PHP を使用してデータベース内の最初のいくつかのレコードを読み取る方法を説明し、具体的なコード例を示します。まず、データベースに接続し、操作するテーブルを選択したと仮定します。以下は簡単なデータベース接続の例です。

Javaでデータベースに接続するときにSQLExceptionに対処するにはどうすればよいですか? Javaでデータベースに接続するときにSQLExceptionに対処するにはどうすればよいですか? Jun 24, 2023 pm 09:23 PM

Java プログラムでは、データベースへの接続は非常に一般的な操作です。データベースへの接続には既製のクラスライブラリやツールを使用できますが、プログラム開発中にはさまざまな異常事態が発生する可能性があり、SQLException もその一つです。 SQLExceptionはJavaが提供する例外クラスで、クエリ文のエラー、テーブルの存在、接続の切断など、データベースアクセス時に発生するエラーを記述します。 Java プログラマ、特に JDBC (Java Data) を使用するプログラマ向け

Go言語でデータベースに接続する方法 Go言語でデータベースに接続する方法 Dec 12, 2023 pm 03:51 PM

Go 言語は、データベース ドライバーをインポートし、データベース接続を確立し、SQL ステートメントを実行し、プリペアド ステートメントとトランザクション処理を使用してデータベースに接続します。詳細な導入: 1. データベース ドライバーをインポートし、github.com/go-sql-driver/mysql パッケージを使用して MySQL データベースに接続します; 2. データベース接続を確立し、データベース アドレス、ユーザーなどのデータベース接続情報を提供します。名前、パスワードなど。sql.Open 関数を通じてデータベース接続などを確立します。

Go 言語を使用してデータベースに接続する: アプリケーションのパフォーマンスと効率を向上させる Go 言語を使用してデータベースに接続する: アプリケーションのパフォーマンスと効率を向上させる Jan 23, 2024 am 08:57 AM

Go 言語を使用したデータベースへの接続: アプリケーションのパフォーマンスと効率の向上 アプリケーションが開発され、ユーザー数が増加するにつれて、データのストレージと処理がますます重要になります。アプリケーションのパフォーマンスと効率を向上させるには、データベースを適切に接続して操作することが重要です。 Go 言語は、高速で信頼性が高く同時実行性の高い開発言語として、データベース処理時に効率的なパフォーマンスを提供する可能性があります。この記事では、Go 言語を使用してデータベースに接続する方法を紹介し、いくつかのコード例を示します。 Go言語を使用してデータベースドライバーをインストールする

PHP を使用して製品在庫数カウントを実装するための手順とテクニック PHP を使用して製品在庫数カウントを実装するための手順とテクニック Aug 18, 2023 am 08:39 AM

PHP で製品在庫を実装する手順とテクニック 電子商取引業界では、製品在庫管理は非常に重要なタスクです。タイムリーかつ正確な在庫カウントにより、販売の遅延、顧客からの苦情、在庫エラーによるその他の問題を回避できます。この記事では、PHP を使用して製品在庫カウントを実装する手順とテクニックを紹介し、コード例を示します。ステップ 1: データベースを作成する まず、製品情報を保存するデータベースを作成する必要があります。 「inventory」という名前のデータベースを作成し、次に「prod」という名前のデータベースを作成します。

Go 言語入門: データベース接続の基本概念 Go 言語入門: データベース接続の基本概念 Jan 23, 2024 am 08:17 AM

Go 言語を学ぶ: データベースへの接続に関する基本的な知識、特定のコード サンプルが必要です。Go 言語はオープン ソース プログラミング言語です。そのシンプルで効率的な機能により、ますます多くの開発者に愛され、使用されています。開発プロセスでは、データの読み取り、書き込み、更新、削除などの操作を実行するためにデータベースとの接続を確立することが必要になることがよくあります。したがって、Go 言語でデータベースに接続する方法を学ぶことは非常に重要なスキルです。データベース ドライバー Go 言語では、データベースに接続するためにデータベース ドライバーが必要です。現在、Go 言語の主なデータベース ドライバーは次のとおりです。

Ubuntu システムに PHP をインストールして構成し、MSSQL データベースに接続する方法 Ubuntu システムに PHP をインストールして構成し、MSSQL データベースに接続する方法 Feb 29, 2024 am 10:06 AM

MSSQL データベースに接続するために Ubuntu システムに PHP をインストールして構成することは、特に Web アプリケーションを開発する場合に一般的なタスクです。この記事では、具体的なコード例を示しながら、Ubuntu システムに PHP、MSSQL 拡張機能をインストールし、データベース接続を構成する方法を紹介します。ステップ 1: PHP および MSSQL 拡張機能をインストールする PHP をインストールする まず、PHP が Ubuntu システムにインストールされていることを確認する必要があります。 PHP は次のコマンドでインストールできます: sudoaptu

MySQL の Jar パッケージの重要な機能は何ですか? MySQL の Jar パッケージの重要な機能は何ですか? Mar 01, 2024 pm 09:45 PM

タイトル: MySQL の Jar パッケージの重要な機能は何ですか? MySQL は、多くの Java 開発者がアプリケーション開発時に使用する人気のリレーショナル データベース管理システムです。 Java プロジェクトで MySQL データベースと対話するには、通常、MySQL が提供する公式の Java ドライバー Jar パッケージが使用されます。 MySQL の Jar パッケージには多くの重要な機能があり、この記事ではその一部を紹介し、具体的なコード例を示します。 1.MySに接続する

See all articles