PHPで次月、前月の出すときの注意点

PHPで次月や前月を抽出するときに注意するべき点。

私は下記の方法で処理してました。

■次月を出力

date("n", strtotime("+1 month"))

上記方法だと特定の日で予想と違う結果が返ってくる

1/30、1/31に処理を見ると結果は「3月」になってしまう。
「2月」が返ってきてほしいが…

1/30に見ると処理は今日の日付の”月”に+1するので「2/30」→「3/1」となり、
結果は「3月」となってしまう。

これを回避するために下記の処理にすること

date('n', strtotime(date("Y-m-01") . ' +1 month'))

しっかりと「01」と指定してあげることで回避できる。

PHPのエラーを表示する

PHPでエラーが表示されずに困っていてその調整で初めて知ったこと。

PHPのエラー表示には「display_errors」を使います。
これがOffになっているとエラーが表示されません。

今回これがOnになっているのにエラーが表示されないのです。
PHPのバージョンは5.6.x

htaccessを見てみると下記の通り

php_value error_reporting "E_ALL & ~E_NOTICE & ~E_DEPRECATED"
php_value display_errors On

お判りいただけただろうか…

正解は下記です。

php_value error_reporting 24567
php_value display_errors On

なんと!htaccessで記述する場合はE_ALLのような定数を使ってはいけないのです。
数値で記述するとちゃんと認識されます!

各定数の数値はこちらで調べてください。

あー 知らなかった~
勉強なりました。

SSLとセッション

当然のことかもしれないけど、知らなかったので結構はまってしまった。

SSLとセッションの読み書き
SSL内ではnonSSLとは違うセッションが発行される。

SSL内
○ SSL内セッションの読み書き
○ nonSSLセッションの読み書き

nonSSL内
× SSL内セッションの読み書き
○ nonSSLセッションの読み書き

当然だけどnonSSLからSSLのセッションにはアクセスできない。

SSLとnonSSLが混在しているサイトはセッションの扱いに気をつけないといけない。

セッション使うならサイト全体をSSLにしちゃったほうが悩まずにすみますね。

OAuth2の認証を使う(Misoca API)

OAuth2の認証を使う(Misoca API)

Misoca(ミソカ)のAPIを使ってみよう!
OAuth2の認証を使っているということなのでOAuth2のことを調べてみた。

■Misoca(ミソカ)
Misocaにアカウントを登録してAPIの準備をします。

Misoca APIのドキュメント
https://doc.misoca.jp/
Misoca API v1
https://doc.misoca.jp/v1/
Misoca API v3
https://doc.misoca.jp/v3/

上記ドキュメントの「アプリケーション登録」の手順でAPIの準備をします。
・Application Id
・Secret
・Callback urls
上記の3つの値をメモします。

■OAuth2
https://github.com/thephpleague/oauth2-client

OAuth2の認証は上記ツールを使いました。
ダウンロードしたバージョンは2.4.1です。

上記バージョンだとPHP5.6、7~7.3まで対応です。

Composerで必要ツールを用意します。

#-- ディレクトリの移動(oauthフォルダを作ってそちらに)
$ cd oauth
#-- composerで必要ツールを取得
$ composer require league/oauth2-client

 

プログラムコード

README.mdの中に記載のあるコードを使いましょう。
修正したものが下記になります。

$provider = new \League\OAuth2\Client\Provider\GenericProvider([
    'clientId'                => '*************************',    // The client ID assigned to you by the provider
    'clientSecret'            => '*************************',   // The client password assigned to you by the provider
    'redirectUri'             => 'http://********/your-redirect-url/',
    'urlAuthorize'            => 'https://app.misoca.jp/oauth2/authorize',
    'urlAccessToken'          => 'https://app.misoca.jp/oauth2/token',
    'urlResourceOwnerDetails' => '',
    'scopes'=>'write'
]);

// If we don't have an authorization code then get one
if (!isset($_GET['code'])) {
    // Fetch the authorization URL from the provider; this returns the
    // urlAuthorize option and generates and applies any necessary parameters
    // (e.g. state).
    $authorizationUrl = $provider->getAuthorizationUrl();

    // Get the state generated for you and store it to the session.
    $_SESSION['oauth2state'] = $provider->getState();

    // Redirect the user to the authorization URL.
    header('Location: ' . $authorizationUrl);
    exit;

// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || (isset($_SESSION['oauth2state']) && $_GET['state'] !== $_SESSION['oauth2state'])) {

    if (isset($_SESSION['oauth2state'])) {
        unset($_SESSION['oauth2state']);
    }
    
    exit('Invalid state');

} else {
    try {
        // Try to get an access token using the authorization code grant.
        $accessToken = $provider->getAccessToken('authorization_code', [
            'code' => $_GET['code']
        ]);

		// APIにリクエストを送信(見積もりの作成)
		// $mitsumoriに見積もりの配列を入れます。詳細はMisocaのドキュメントを確認
		$request = $provider->getAuthenticatedRequest(
			'POST',
			'https://app.misoca.jp/api/v3/estimate',
			$accessToken,
			array(
				"body"=>json_encode($mitsumori),
				'headers' => array(
					'Content-Type' => 'application/json;charset=UTF-8', // このヘッダーがないと返りがうまくいかない
				),
			)
		);

		// APIからのレスポンスを取得
		$response = $provider->getResponse($request);
		// レスポンスのボディ部分を取得
		$data = $response->getBody()->getContents();

		// JSONで返ってきているのでデコード
		$result = json_decode($data, true);

		session_destroy();// セッションを削除

    } catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {

        // Failed to get the access token or user details.
        exit($e->getMessage());

    }

}

 

●修正内容
2~7行目を修正
8行目に「scopes」を追加

41~63行目を追加・修正
リクエスト&レスポンスを追加
詳しくはMisocaのドキュメントを確認してください

OAuth2にすごい時間かかりました・・・(疲

htaccessでerror_reportingの変更

htaccessでerror_reportingを変更する場合にはまったので備忘録

php_value error_reporting E_ALL

 

上記のような感じで書いちゃうと動かないみたいだ。

htaccessで指定する場合はビット値での指定が必須のようです。

各値は公式サイトを参考に。

E_ALLを指定する場合は「32767」を指定
※PHP5.4は32767、5.3は30719、5.2は6143、それ以前は2047とバージョンによって若干値が変わります。

E_ALL & ~E_NOTICE & ~E_DEPRECATED

例えば上記を指定したい場合

E_ALL:32767
E_NOTICE:8
E_DEPRECATED:8192

NOTの分を引き算します。
32767 – 8 – 8192 = 24567

php_value error_reporting 24567

 

となる。

PDOでMySQLの操作をしてみる

PHP7での話し。
PHP7ではMDB2が動かなかったので、PDOでDB操作をしてみたの。

かなり簡単だけどサンプルコードを作ってみましたのよ。

# DB接続
$con = new PDO("mysql:host=$host;dbname=$dbname", $usr, $passwd);

# 検索
$select = "SELECT count(*) as cnt FROM mail WHERE mail = '$mail'";
$stmt = $con->query($select);
if(!$stmt){
	echo '検索に失敗しました。';
	exit;
}
$cnt = $stmt->fetch(PDO::FETCH_ASSOC);

if(!$cnt["cnt"]){
	# データ登録
	$insert  = "INSERT INTO mail (mail, date) ";
	$insert .= "VALUES('$mail', '".date("Y-m-d H:i:s"). "')";
	if(!$con->query($insert)){
		echo 'データの登録に失敗しました。';
		exit;
	}
}

$stmt = null;// クリア
$con = null;// クリア

PHPのショートタグ

サーバー移転時にショートタグで書いているプログラムがたくさんあった。

ショートタグ↓こんなやつ

<? for($i=0; $i<10; $i++){ .... } ?>

全部修正は無理なのでショートタグを許可しちゃいます。

.htaccessに下記を記載

php_flag short_open_tag on

Deprecated警告の消し方

Deprecated: Function ereg_replace() is deprecated in ~~~~

PHP5.3から上記警告が表示されるようになっています。
将来的にサポートされなくなる関数を使用した場合に表示される警告です。

その関数を修正するのが良いのですが、状況によっては修正に時間がかかる場合もありますね。

php.iniや.htaccess、ソースで表示をOFFの設定が可能です。

php.iniの場合(要Apacheのリロードor再起動)

error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED

.htaccessの場合

php_value error_reporting "E_ALL & ~E_NOTICE & ~E_DEPRECATED"

ソースの場合

error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED);