ラベル MySQL の投稿を表示しています。 すべての投稿を表示
ラベル MySQL の投稿を表示しています。 すべての投稿を表示

2021年12月6日月曜日

PHP ip2longの罠(2) ローカルIPアドレスが '::1'

XAMPPを使った cakePHP3のローカルな開発環境でブラウザ表示させる際に、$_SERVER['REMOTE_ADDR']を使ってIPアドレスを取得すると、localhostでは '::1' という値が返されてきた。

プログラムでは ip2long()関数を使って数値化されたIPアドレス値をデータベースに照合しているので、これじゃ使えない。

  $ip_address = $_SERVER['REMOTE_ADDR'];
  $ip_value = ip2long($ip_address);

実際、$ip_address='::1' の場合に $ip_value=ip2long('::1');を実行すると false が返ってきてしまっている。

WEBを検索すると、次の情報があったのでやってみた。(コントローラ内での呼び出し)

  $ip_address = $this->request->clientIp();

これでも、値は '::1' となる。こまったぞ・・・

よくよく考えると、自分のIPを返せばいいわけで。
次のコードでうまくいくようになった。

if($_SERVER["HTTP_HOST"] == "localhost")
{
	$ip_address = getHostByName(getHostName());
}
$ip_value = ip2long($ip_address);

無事取得できました。
めでたしめでたし。

2021年11月8日月曜日

PHP ip2longの罠

cakePHPのサーバー運用も多くやってますが、もっぱら cakePHP3.9 で作業することが多いです。
担当外の cakePHP1.2で構築されたサーバーくんのトラブルに駆り出されてみたので、そのお話です。

機器との接続がうまく行かないと言われましてですね。
機器は MySQLのテーブルに IPアドレス が記録されていまして、それを読み込んでアクセスしているわけです。

php には、ip2long(), long2ip() という関数が用意されていて、IPアドレスを整数値に変換したり逆に整数値をIPアドレスの文字列に変換できたりするわけで
データベースに文字列でIPアドレスを格納するよりも数値で格納しておく方が効果的なので、よく使われます。

たとえば、192.168.3.20 というIPアドレスを変換してDBに格納する場合は Windows10標準の電卓でHEX入力するといい。
192=C0, 168=A8, 20=14 なので、HEX(16進数)入力で C0A80314 と入力すると、DEC(10進数)部分に 3,232,236,308 が表示される。
DBには、この値 3232236308 を入れてしまえばいいわけ。

しかしだ。
動いてくれないのだよ。
なぜじゃ!?

ローカルに環境を構築する暇なんてなかったので、なかなかデバッグしづらい環境だったけど、原因を突き止めました。


Windows電卓は64bit演算なのですよ。
ターゲットの環境は32bit環境。

2148483647(0x80000000)以上の数値は long なので負数になるべきなのだYO!

ということで、2の補数を使って負数に変換しなきゃいけない。
64bit環境上に、こんなプログラムを作ってみました。

<?php
/*
    ip2long 32bit 処理
*/
$half = ip2long('128.0.0.0');   // 2148483647

$msg = '';
if(isset($_GET['ip']))
{
    $ip = $_GET['ip'];
    $long = ip2long($ip);
    if($half <= $long)
    {
        //MSB が1
        $long = ($long ^ (16 ** 8-1)) + 1;
        $long = 0 - $long;
    }
    $msg .= 'ip:' . $ip . ' value:' . $long;
}
?>

<HTML>
<BODY>
    <DIV>
        <?= $msg ?>
    </DIV>
</BODY>
</HTML>

https://seasoft.co.jp/bin/ip2long32.php で実際に動作できます。
2の補数なんて久しぶりに使ったから、ちょっと時間かかちゃったよ笑


めでたし、めでたし。

2021年9月17日金曜日

cakePHP で開発環境とレンタルサーバでデータベースを日本時間にする

 cakePHP3.9 をXAMPP上で開発しているプロジェクトをレンタルサーバ(XSERVER)上で動作させようとしたら、データベースの日本時間設定がうまくいかなかったので、まとめてみます。

まず、あちこちのサイトに書いてあるこの方法。

config/app.php

'App' => [
   ;
        'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'Asia/Tokyo'),
   ;
'Datasources' => [
        'default' => [
                ;
            'timezone' => 'Asia/Tokyo',
                ;

この方法では XAMPP上のプロジェクトはちゃんと動作するけど、XSERVERで実行すると
Unknown or incorrect time zone: 'Asia/Tokyo'
というエラーが発生して、動作しません。

別のWEBサイトでの方法では、'Asia/Tokyo' の代わりに 'JST' を指定すればOK
という情報もありましたが・・・
Unknown or incorrect time zone: 'JST'
XSERVERでは動きませんでしたね。

MySQL の mysql テーブル timezoneをインポートして設定するといいのでしょうけれど
XSERVERでそれをやる方法がわかりませんでした

で、最終的にうまくいった方法を披露しておきます。

'App' => [
   ;
        'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'Asia/Tokyo'),
   ;
'Datasources' => [
        'default' => [
                ;
            'timezone' => '+9:00',
                ;

Datasources側だけ、timezoneを '+9:00' に設定するわけです。
これでデータベース内の記録日時とWEBサイトで表示される日時を同期させることができました。
めでたし、めでたし。