PG WORKS

PHPやLinux(サーバー)などのノウハウや、便利なツールを紹介していきます。

【Apache】htaccessを使ったリダイレクト設定

PHPネタ以外で今回は「htaccess」を使ったリダイレクト設定の仕方を紹介したいと思います。

リダイレクトを使う理由としては。。。

  • サイトのドメイン変更で新しいドメインへリダイレクト
  • 特定のページを別のページへリダイレクト
  • www無しをwww有りにしてリダイレクト

他にも、URLの書き換えや、PHPの設定変更も「.htaccess」で対応が可能です。

では、リダイレクトのサンプルを記載していきたいと思います。

別のページへリダイレクト

Redirect permanent /old/ http://newsite.net/new/

リダイレクトしたいページ名とリダイレクト先のURLを記載します。日本語URLでは、リダイレクト先のURLをPunycode(ピュニコード)で記載します。

Punycodeに変換したい場合、下記のサイト様が大変便利です。
n7.com

別のページへリダイレクト(日本語の場合)

Redirect permanent /過去履歴/ http://newsite.net/xn--fht636a/

※過去履歴からhttp://newsite.net/履歴/にリダイレクト
また、特定のフォルダにあるページを全て同じURLにリダイレクトしたい場合は、下記の書き方になります。

対象のフォルダにあるページを全て同じURLへリダイレクト1

RedirectMatch permanent /website/* http://newsite.net/new/

下記の方法でも、一括リダイレクト可能です。

対象のフォルダにあるページを全て同じURLへリダイレクト2

RewriteCond %{SERVER_PORT} 80
RewriteRule ^website/(.*)$ http://newsite.net/new/ [R=301,L]


次回は、同じ「htaccess」を使ったURLの書き換え方法を紹介したいと思います~。

【PHP】Noticeを回避するためにisset関数を使おう

php本体側の設定で、E_NOTICEの設定がないとき、値が入っていない変数や配列を見に行くと、「Notice: Undefined index」が表示されます。

普段は、php.iniやphpファイルのini_setなどで、NOTICEを無視したりと、結構雑な感じに扱われますが、仕事の都合でNOTICEエラーも対応することが多々あります。

NOTICEが表示される書き方

<?php
  if( $sample == "zen6a" ) {
    echo 'zenです。';
  } else {
    echo 'zenではないです。';
  }
?>

上記の書き方だと、if文でNOTICEが表示されます。
また、「empty」や配列の件数を確認する「count」を使用しても表示されてしまいます。(めんどry

NOTICEの回避方法

<?php
  if( isset($sample) == "zen6a" ) {
    echo 'zenです。';
  } else {
    echo 'zenではないです。';
  }
?>

同じサンプルに、if文にisset関数を付け加えました。
これで、$sampleに値が入ってなくてもNOTICEが表示されることはありません。

また、次のサンプルは連想配列でissetを利用した書き方になります。

連想配列のNOTICEの回避方法

<?php
  if( isset($aryData[@key($aryData)]) ) {
    echo '配列の中に値あります。';
  }
?>

強引な書き方かもしれませんが、key関数を使い連想配列名を取得して値を確認しています。

もっといいやり方があると思いますので、こちらは随時更新していきたいと思います。

【PHP】FTPアップロード機能を作ろう。

体調元に戻ったのですが、久々にモンスターエナジー飲んだらお腹の調子が悪いZENです(汗

今回のプログラム紹介記事は、ファイルのアップロード機能になります。

また、プログラムのサンプルですが、comeonly様から、少しプログラムを変更しての紹介です。
comeonly.hatenablog.com

FTPアップロード関数

<?php
/**
 * 指定したファイルをアップロード
 * $ftp ↓配列の中身
 *   ftp_server
 *   ftp_user_name
 *   ftp_user_pass
 * $remote_file アップロード先
 * $file アップロードするファイルorディレクトリ
 **/
function FTPuploads($ftp, $remote_file, $file) {
  // 接続を確立する
  $conn_id = ftp_connect(trim($ftp['ftp_server']));
  ftp_pasv($conn_id, true);	
  if (!$conn_id) {
    die($ftp['ftp_server'].'接続できません' . "\n");
  }
	
  // ユーザ名とパスワードでログインする
  $login_result = ftp_login($conn_id, trim($ftp['ftp_user_name']), trim($ftp['ftp_user_pass']));

  if (!$login_result) {
    die('ログインできません'.$ftp['ftp_server']. "\n");
  }
	
  // フォルダの場合作成
  if( is_dir($file) ) {
    $contents_on_server = ftp_nlist($conn_id, $remote_file);
    if(!in_array($remote_file."/.", $contents_on_server)) {
      if(!ftp_mkdir($conn_id, $remote_file)) {
        echo "There was a problem while creating $file\n";
        exit;
      }
    }

  // ファイルをアップロードする
  } else {
    if (!ftp_put($conn_id, $remote_file, $file, FTP_ASCII)) {
      echo "There was a problem while uploading $file\n";
      exit;
    }
  }

  // 接続を閉じる
  ftp_close($conn_id);
}

/**
 * 指定したディレクトリの一括アップロード
 **/
function AllFTPUpload( $ftp, $targetDir, $subPath="" ) {
  $aryDirs = list_targetfiles($targetDir);
  if( is_array($aryDirs) ) {
    foreach( $aryDirs as $dvals ) {
      $filePaths = str_replace($targetDir, "", $dvals);
      FTPuploads($ftp,$subPath.$filePaths,$dvals);
    }
  }
}
/**
 * 全ての階層のファイル/フォルダを取得する
 * $dir 指定したディレクトリの全階層取得
 * 
 **/
function list_targetfiles($dir){
   $files = array();
   $list = scandir($dir);
   $aryNotDir = array("design");
   foreach($list as $file) {
     if($file == '.' || $file == '..') {
        continue;
     } else if(is_file($dir . $file)) {
        $files[] = $dir . $file;
     } else if(is_dir($dir . $file)) {
        $files[] = $dir . $file;
        $files = array_merge($files, list_files($dir . $file . '/'));
     }
   }
  return $files;
}
?>

指定した、ディレクトリを一括でアップロードできるように変更してみました。

特定のファイルだけアップロードする場合は「FTPuploads」関数のみで、ディレクトリにある中身すべてをアップロードする場合は、「AllFTPUpload」を使用する形です。

アップロード完了後、元ファイルを削除したい場合、でじうぃき様のファイル削除関数を使用すると便利です。
onlineconsultant.jp

【PHP】$_REQUESTの優先順位

PHPの$_REQUESTを使用すると、GETとPOSTの値を両方取得してくれる便利なリクエスト変数があります。

また、$_REQUESTは、$_COOKIEの値も取得できるそうですが、さくらVPSでは設定されていませんでした。

確認方法は、「php.ini」の下記のコードから判断できます。

php.ini

682行目:request_order = "GP"

記号の意味は、下記の通りです。

G : $_GET
P : $_POST
C : $_COOKIE

私自身、今まで変更したことはないのですが、レンタルサーバによっては設定が異なる場合があります。

ぺんたんさんのサイトで検証コードがありますので、一度確認してみましょう~^^
$_REQUESTに入る値と、その優先順位 - [PHP + PHP] ぺんたん info

【PHP】メール送信関数「mb_send_mail」をカスタマイズ

簡易的にメール送信関数を呼べるように、関数化してみました。

メール送信関数プログラム

<?php
function sendmailCustom( $mailTo, $mailFrom, $mailTitle, $mailBody ) {
  mb_language("Japanese");
  mb_internal_encoding("UTF-8");

  if( mb_send_mail( $mailTo, $mailTitle, $mailBody, "From: ".$mailFrom ) ) {
      return true;
  }else{
      return false;
  }
}
?>

引数は、下記の4つを指定すると、メールが送信される仕組みになっています。

「$mailTo」メールを送信する先のアドレスを指定
「$mailFrom」送信元のメールアドレスを指定(任意)
「$mailTitle」メールタイトル
「$mailBody」メール内容

UTF-8の環境でメールを送信しているため、送信先UTF-8に対応していないと文字化けする可能性があります。

「cron」で動かしているプログラムがあれば、エラーが発生したときにメールを送る仕組みを作っていれば、いち早く不具合対応できると思います。