カテゴリー : PHP

PHPで特定の月の日数を取得する

PHPで特定の月の日数を取得したい

ということがあったのでメモ。

やることは簡単です。

取得したい月の末日を求めます。

末日の日付を取得したい場合には、

date('Y-m-t');

というように、日付に「t」を使います。

その月の日数は、末日の日付とイコールなので、

date('t');

で求められます。

特定の月の日数を求める場合はstrtotimeを使用して

date('t', strtotime($date));

というようにします。

先月の日数を求める場合は、

date('t', strtotime('-1 month'));

とします。

PHPでURLが存在するかを調べる方法

PHPで、入力されたURLが実際に存在するかを

チェックする処理を実装したので、その時のメモ。

以下を使う方法があります。

1.get_headers

2.fopen

3.file_get_contents

結局、get_headersを使う方法を採用しました。

get_headers()は、HTTP リクエストに対するレスポンス内で

サーバーによって送出されたヘッダの配列を返すので、

この中からステータスコードが200であるかを

チェックします。

以下のように実装しました。


$header = @get_headers($url);
if(preg_match('#^HTTP/.*\s+[200]+\s#i', $header[0])) {
return true;
} else {
return false;
}

以下のサイトを参考にさせてもらいました。

PHPでURLが存在するか確認する方法

URLが実際に存在するかどうかを調べる方法(PHP)

PHPのファイルダウンロードでのファイル名文字化け対応

PHPでファイルダウンロードが画面を作ったのですが、

ユーザーさんからダウンロードしたファイルが文字化けする

という報告があり調査しました。

私が普段使っているのはGoogle Chromeなのですが、

Chromeでは文字化けは起こっていませんでした。

ユーザーさんに確認すると、使用しているブラウザは

IEとのこと。

IEで試してみると、やはり文字化けしました。

ダウンロードする処理は以下のように書いていました。


header("Content-Type: application/octet-stream;");
header("Content-Disposition: attachment;filename=".$file_name);
echo file_get_contents($file_name);

文字化けするのなら文字コードを変えてやればいいということで

mb_convert_encodingを使ってみます。


header("Content-Type: application/octet-stream;");
header("Content-Disposition: attachment;filename=".mb_convert_encoding($file_name, 'sjis-win', 'UTF-8'));
echo file_get_contents($file_name);

サーバー上のプログラム、DBはUTF-8なので、

UTF-8からWindows用にShift-JISに変換します。

これで文字化けは解消しました。

IEだけではなく、念のためChromeで試しても文字化けせず。

PHPでCSVダウンロード画面を作ったがCSVファイルを開くとエラーが表示される件

PHPでCSVダウンロード画面を作ったのですが、

ダウンロードしたCSVファイルをエクセルで開くと

エラーが表示されてしまうので調べました。

エラー内容は、以下のようなものです。

開こうとしているファイル ‘***.***’ の形式は ファイル拡張子が示す形式と異なります。

Excel は ‘xxxx.csv’が SYLK ファイルであることを確認しましたが、読み込むことができません。ファイルにエラーが含まれるか、SYLKファイル形式でない可能性があります。異なるファイル形式でそのファイルを開くには、[OK]をクリックしてください。

テキストエディタでCSVファイルを開いてみても、

おかしな点は見つかりませんでした。

同じエラーで困っている方がいらっしゃるようです。

CSVファイルの先頭を「ID」で始めるとSYLK形式として

読み込もうとするためこのようなエラーが発生するようです。

マイクロソフトのサポートページには、回避策として

先頭の文字列”ID”の前にスペースを入力する方法が掲載されていました。

■参考
【Excel】SYLK ファイルであることを確認しましたが、読み込むことができません

[PJ98]CSV形式で保存したファイルをExcelで開くとエラー発生

PHPで日付計算する方法のまとめ

PHPで「現在から○日後」「ある日から○カ月後」の日付を求めたい

ということがよくあるのでまとめてみました。

strtotimeを使います。

strtotimeは、「英文形式の日付をUnixタイムスタンプに変換する」関数です。

int strtotime ( string $time [, int $now = time() ] )

以下のように使用します。

strtotime("now");

strtotime("+1 day");

strtotime("next Thursday");

1週間後の日付を求める場合は以下のように書きます。

echo date('Y-m-d', strtotime('+1 week'));

1か月と10日後の日付はこうなります。

echo date('Y-m-d', strtotime('+1 month 10 days'));

ある特定の日から○日前というのも求められます。

strtotimeの2番目の引数に、特定の日を入れます。

echo date('Y-m-d', strtotime('+1 month', strtotime('2014-03-12')));

上記は、「2014年3月12日の1カ月後の日付」を表示します。

PHPでディレクトリごとコピーする

PHPのcopy関数は、ファイルのコピーを行いますが、
ディレクトリごとコピーすることができません。

ディレクトリごとコピーする方法がないか調べていたところ、
そのものズバリの関数を作成されている方がいらっしゃったのでそのまま使わせてもらいました。

//------------------------------------------------------------------------------
// ディレクトリ階層以下のコピー
// 引数: コピー元ディレクトリ、コピー先ディレクトリ
// 戻り値: 結果
function dir_copy($dir_name, $new_dir)
{
  if (!is_dir($new_dir)) {
    mkdir($new_dir);
  }

  if (is_dir($dir_name)) {
    if ($dh = opendir($dir_name)) {
      while (($file = readdir($dh)) !== false) {
        if ($file == "." || $file == "..") {
          continue;
        }
        if (is_dir($dir_name . "/" . $file)) {
          dir_copy($dir_name . "/" . $file, $new_dir . "/" . $file);
        }
        else {
          copy($dir_name . "/" . $file, $new_dir . "/" . $file);
        }
      }
      closedir($dh);
    }
  }
  return true;
}

以下のサイトを参考にさせて頂きました。
・ディレクトリ全コピー関数 | Search A.I.

CakePHPでラジオボタンを使用する

CakePHPでラジオボタンを使用する方法です。
性別を選択するラジオボタンを表示します。

<?php
$options = array('m'=>'男性', 'f'=>'女性');
echo $this->Form->radio('sex', $options, array('legend' => false));
?>

$optionsで選択肢を配列で指定します。

CakePHPで、郵便番号から住所を自動入力したい

会員登録画面などで、郵便番号を入力すると、住所が自動入力されるというのはよく見かけます。
これをCakePHP上で実装したので、メモ。

自動入力には、ajaxzip2を使用します。
ajaxzip2のサイトから、ajaxZip2のアーカイブをダウンロードします。

解凍したajaxzip2をフォルダごとwebroot/js/におきます。
webroot/js/ajaxzip2/というフォルダ内に、
ajaxzip2.jsファイル、dataフォルダ、workフォルダが配置される形です。

viewファイルに、ajaxzip2を呼び出すように記載します。
jQueryを使用します。

<?php
echo $this->Html->script('jquery-1.9.1');
echo $this->Html->script('ajaxzip2/ajaxzip2');
?>

都道府県の選択肢を全て書いてもいいのですが、せっかくなのでDB化します。
prevesというテーブルを作成します。

CREATE TABLE IF NOT EXISTS `preves` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id` (`id`)
);

データを登録します。

INSERT INTO `preves` (`id`, `name`) VALUES
(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, '沖縄県');

モデル(app/Model/Pref.php)を作成します。
クラスの定義だけです。

<?php
App::uses('AppModel', 'Model');

class Pref extends AppModel {
}
?>

コントローラーで、都道府県データを取得します。
Prefモデルを使用したいので、$usesにPrefを追加します。

var $uses = array('Pref');

コントローラー内で、以下のようにして都道府県データを取得します。

$pref_arr = $this->Pref->find('list', array('fields' => array( 'id', 'name')));
$this->set('pref_arr', $pref_arr);

Viewファイルで以下のように指定します。
Hogeはコントローラー名です。都道府県、市区町村のinputタグのnameがdata[Hoge][pref]となるので、
郵便番号の項目指定の箇所はこれに合わせます。

郵便番号: <?php echo $this->Form->input('zip', array('type'=>'text', 'div'=>false, 'label'=>false, 'size'=>"10", 'maxlength'=>"8", 'onKeyUp'=>"AjaxZip2.zip2addr(this,'data[Hoge][pref]','data[Hoge][address]',null,'strt');")); ?>
都道府県: <?php echo $this->Form->input('pref', array('type'=>'select', 'div'=>false, 'label'=>false, 'options'=>$pref_arr, 'empty'=>'選択してください')); ?>
住所: <?php echo $this->Form->input('address', array('type'=>'text', 'div'=>false, 'label'=>false, 'size'=>40)); ?>

最後に、ajaxzip2内のdataファイル呼び出しがパスの関係でうまくいっていなかったので修正。
js/ajaxzip2/ajaxzip2.jsの31行目を実際の環境にあわせて修正します(先頭にjsを追加)。

AjaxZip2.JSONDATA = 'js/ajaxzip2/data';

以上で使用できるようになると思います。

CakePHPで登録したレコードのIDを取得する

CakePHPで、登録したレコードのIDを取得する方法です。
getLastInsertID()を使用します。

$this->Model->save();
で保存した後に、以下で取得できます。

[sorcecode]
$hoge_id = $this->Model->getLastInsertID();
[/sorcecode]

CakePHPでセレクトボックスを表示する

CakePHPでセレクトボックスを表示する方法のメモ。

まず、コントローラーに選択肢の配列を指定します。
例えば、業種を選択するセレクトボックスを表示します。
コントローラー全体で使用したいので、beforeFilterで指定します。

	function beforeFilter() {
		parent::beforeFilter();

		$category_arr = array(
			"1" => "農業・林業・漁業", 
			"2" => "鉱業", 
			"3" => "建設業", 
			"4" => "製造業", 
			"5" => "電気・ガス・水道業", 
			"6" => "情報通信業", 
			"7" => "運輸業", 
			"8・小売業" => "卸売・小売業", 
			"9" => "金融・保険業", 
			"10" => "不動産業", 
			"11" => "飲食店・宿泊業", 
			"12" => "医療・福祉", 
			"13" => "教育・学習支援業", 
			"14" => "複合サービス事業", 
			"15" => "サービス業", 
			"16" => "公務"
			);
		$this->set('category_arr', $category_arr);
	}

次はViewです。

<?php echo $this->Form->input('category', array('type'=>'select', 'div'=>false, 'label'=>false, 'options'=>$category_arr, 'empty'=>'選択してください')); ?>

div、labelタグを表示したくないので、それぞれfalseを指定しています。
optionsに、コントローラーで指定した配列を設定します。
emptyは、空の選択肢を指定します。

これで、以下のようにselectタグが出力されます。

<select name="data[Hoge][category]" id="HogeCategory">
<option value="">選択してください</option>
<option value="1">農業・林業・漁業</option>
<option value="2">鉱業</option>
<option value="3">建設業</option>
<option value="4">製造業</option>
<option value="5">電気・ガス・水道業</option>
<option value="6">情報通信業</option>
<option value="7">運輸業</option>
<option value="8・小売業">卸売・小売業</option>
<option value="9">金融・保険業</option>
<option value="10">不動産業</option>
<option value="11">飲食店・宿泊業</option>
<option value="12">医療・福祉</option>
<option value="13">教育・学習支援業</option>
<option value="14">複合サービス事業</option>
<option value="15">サービス業</option>
<option value="16">公務</option>
</select>

Hogeはコントローラー名です。