きょろきょろ(๑´• ₃ •̀๑)

特にWeb系についてのことを書いていきたいと思います。 基本的にメモ書きみたいなものです。

PHPでソケット通信(UDP)

今回、PHPでソケット通信を行いました。
環境としては、C言語でクライアント側(UDPを送る)を行い、PHPでサーバ側を行うというものでした。今回C言語のクライアント側は元々あるものとし、PHP側のサーバを作成しました。作成したPHPのコードを以下に示します。

<?php
	class packet_format{
		public $type;
		public $message;
		public $recv_date;
	}
	
	$recv_data = new packet_format;
	$port = 5050;

	//UDPのソケット作成
	$sock = socket_create(AF_INET,SOCK_DGRAM,SOL_UDP);
	socket_bind($sock,'127.0.0.1',$port);
	$from = '';
	while(true){
		//UDPのソケットを受信
		socket_recvfrom($sock,$buf,4096,0,$from,$port);
		//バイナリで取得しているため、unpackでデータを取得
		$packet_data = unpack("Stype/Smessage/ITimestamp",$buf);
		
		//対応する変数に代入
		$recv_data->type = $array["type"];
		$recv_data->message = $array["message"];
		$recv_data->recv_date = date('D M d H:i:s Y',$array["Timestamp"]);
		/*
			確認応答パケットをUDPで送信(データは1,2,3,4)
			送るデータをpackでバイナリ文字列にパックした後送る
		*/
		$socket = socket_create(AF_INET,SOCK_DGRAM,SOL_UDP);
		$sock_data = pack('SSSS',1,2,3,4);
		socket_sendto($socket,$sock_data,strlen($sock_data),0,$from,$port);
	}
	//close socket
	socket_close($sock);
        socket_close($socket);
?>

今回の場合はサーバを作成しているため、while文で常に起動させておきます。

UDPのソケットの受信の順序

  • socket_create関数で受信ソケットの作成
  • socket_bind関数でソケットに名前を付ける
  • socket_recvfrom関数でソケットの受信待ち
  • unpack関数でソケットのバイナリデータを解析
  • socket_close関数でソケットを閉じる

UDPの場合はソケットを作成する際に、socket_create関数の第2,3引数には、SOCK_DGRAMとSOL_UDPを指定する。TCPでは、SOCK_DGRAM→SOCK_STREAMで、SOL_UDP→SOL_TCPで行けると思います。
次に、bindでソケットに名前を付けた後、socket_recvfromでパケットの受信を行います。受信後の引数である$fromと$portには、ソケットの送信者のIPアドレスとポート番号の情報が入るみたいです。

次に、受信したバイナリデータ(ソケットからのデータ)をそのままデータとして取得はできませんので、unpack関数を利用し、それぞれのデータとして分解します。戻り値としては、配列として返却します。
unpack関数では、

<?php
    unpack("Stype",$buf);  //array("type"=>Sのデータ);
?>

のように使うのですが、Sは、データのフォーマットでありtypeは、連想配列のkeyの名前となります。

<?php
    unpack("S",$buf);  //array("1"=>Sのデータ);
?>

でも良いのですが、この場合では、配列の添え字が1から始まります。
データのフォーマットについては、送信の際にpack関数を用いるのですが、その時に指定したフォーマットを同様にunpackで指定するとよいと思います。
PHP: pack - Manual
ここにデータのフォーマットが書かれています。

そして、最後はsocket_closeでソケットを閉じておしまいです。


PHPカンファレンス-関西-に行ってきました。

PHPカンファレンス関西に行ってきました!

f:id:ferretdayo:20150531110612j:plain
今回、PHPカンファレンスに合わせて実家に帰省したのですが、前日くらいから体調が悪くて、最後までいることが出来なかったので残念でした。
しかし、自分の勉強のモチベーションと言いますか、自分の実力がどれ程のものなのかということを何となく周りのすごい怖いお人達から得られたのではないのかなと思いました。

セッション

PHP7で変わること 言語仕様とエンジンの改善ポイント

PHPカンファレンスの一番大きな目玉?と言えるPHP7のセッションです!
PHP6は永久欠番らしく、6を飛ばして7らしいですが、どこが変わるのか?ということを紹介されていました。

変わるところ
  • 致命的エラーで例外を出せるようになった。(メソッドがないなどのエラー)
  • タイプヒントが出来るようになった。
  • 非推奨だったmysql関数、ereg関数などの廃止
  • 速度!!!!!!!!
  • 変数の内部構造?zvalとかなんとか

こんな感じですね。
・タイプヒントはできるだけ使っていこうかなぁと思いましたね。
PHPは型がちゃんとしてないとか言われるので、せめてタイプヒントでどのような返り値を返そうとしているのか?というのを示そうかと思いました。
・一番変わったと思われる速度!
ここについては、PHPは他の言語と比べて速度に関するアドバンテージは無くなったと考えていいだろうということをおっしゃっていました。
海外の文献で、v5.6と比べ約2倍速くなったそうです。
・内部構造?についていろいろと変更
変数の管理について、zvalは24byteから16byte減っていたり、参照する回数1回減っているなどと管理に関しても簡略化されているようです?codezine.jp
ここのURLから詳しいことは見れると思うのでここで見てみてください。

PHPフレームワークを俯瞰してみた

これから新しいバージョンが出てくるフレームワークに関していろいろと紹介されていました。

他にも紹介されていたかもしれませんが、忘れました^;
Laravelには、SNSのボタン?TwitterFaceBookのシェアなどのボタンが対応するとか?よくわかっていません←
とにかく、フレームワークに追加する機能の一つ一つの単語について初めて見る単語ばかりであまりついていけてませんでした(笑)

PHPに足りないセキュリティ機能

まず初めに、30分のセッションの中で、スライド数が130くらいあった気がします(最後らへんめっちゃ飛ばしていてめっちゃ言いたいことあるんだろうなぁと思いました。)
PHPには、何が足りないかというと、○○用のエスケープ関数というのが足りないということを言っていました。
XML用などそれ用の関数を用意すべきだよねとおっしゃっていました。
で!このセッションでの重要なお話が
セキュリティで大切なのは入出力バリデーション
ここをちゃんとすることで大体のセキュリティ対策になるそうです。
しかしこういうところをちゃんとするためにも、どのような攻撃手法があるなど、それに関しての知識を付けなければバリデーションもできないと思うので、Webをさわっている方はセキュリティからは逃れることは出来ないのかと思います。

終わりに

ブースでは、ECサイトを作るためのAPI?みたいなのを紹介していたりtwilioさんの電話を用いてアプリケーションを作成出来たりとするAPIがあるということを照会されていたりしました。
twilioでは、ある電話番号にみんなにメッセージを言ってもらって、そのメッセージを処理した後に、ある人にそのメッセージをつなげたものを電話を通して聞いてもらうなどの使い方が出来るそうです。
そしてtwilioさんには、マグカップをいただきました。ありがとうございます!
f:id:ferretdayo:20150531115801j:plain


EclipseからAndroid Studioへの移行(できなかった)

EclipseAndroid Studioの違いは、ぱっといろいろやってみた感じ・・・・

Eclipse
1.Build

Android Studio
 1.Gradle
2.Build

という感じの手順であった。あまり詳しくないので、何も言えないが、Android StudioはGradleのおかげで結構自由なことが出来るのではないのかな?と予想してみたり。

移行では、Android Studioの形式とは違う形でImportしていたりするので、appフォルダとかがなく、調べてもうまいことできませんでした。

何だかんだやってると、Gradleの同期は出来たのですがBuildでErrorが吐かれ、Google-Play-Services_libのapkファイルがないのかなんかそういう系でした。

まぁまたいつか挑戦します。

PHP5.5とPHP5.3のexplode関数の違い?

今回、explode関数を用いて文字列を分割して、その最初のほうだけを表示させようとしたプログラムがあったのですがバージョンの違いにより動かなかったということのメモです。
下のプログラムは、PHP5.5で動かしたときです。

<?php
   $str = "aaaa-bbbb";
   echo explode('-',$str)[0];
?>

結果としては、

aaaa

と表示されるはずです。
しかし、バージョンがPHP5.3の際、このようにするとエラーを吐かれます。
内容としてはexplodeの後ろの[0]が悪かったみたいです。
PHP5.3で表示させたい場合は、まず変数に代入してから、その変数で配列の添え字0番目を指定すればよいみたいです。
このような感じになります。

<?php
   $str = "aaaa-bbbb";
   $tmp = explode('-',$str);
   echo $tmp[0];
?>

このような感じに変数に一旦代入してからechoで表示させてやるとPHP5.3でもエラー吐かれずに済みます。

まぁこんな感じです。

foundationのmodalで、Ajaxを用いた値の受け渡し(php,javascript)

今回、htmlでラジオボックスで選択された場所に応じてmodalのフォームでphpのデータをJavaScriptに渡してjQueryでtextのvalue属性に値を代入するということをしました。

まず、元のページの一部(index.php)を示します。

<form action="./json.php" method="POST" id="modal">
 <div class="row">
  <div class="large-12 columns">
   <table>
    <thead>
     <tr>
      <th>変更</th>
      <th width="100">ID</th>
      <th width="200">商品名</th>
      <th width="100">値段</th>
     </tr>
    </thead>
    <tbody>
    <?php 
     //DBからデータを取得し表示
     foreach($dbdata as $k => $val){
      echo "<tr>";
      echo "<td><input type='radio' name='radio' value='{$k}'></td>";
      foreach($val as $key => $value){
       echo "<td>".$value."</td>";
      }
       echo "</tr>";
     }
       ?>
    </tbody>
   </table>
  </div>
 </div>
 <!-- 変更のTrigger -->
 <div class="row">
  <div class="large-12 columns">
   <input type="submit" class="button info" value="変更">
  </div>
 </div>
</form>
<!-- 変更のModalの内容 -->
<div id="hoge" class="reveal-modal" data-reveal aria-labelledby="hogetitle" aria-hidden="true" role="dialog">
 <div class="row">
  <div class="large-12 columns">
   <h1 id="hogetitle">変更</h1>
  <div>
 </div>
 <!-- form -->
 <form action="" method="POST" data-abide>
    <div class="row">
      <div class="large-12 columns">
	 <label>
	    ID
	    <input type="text" name="p_id" id="p_id" value="" readonly>
         </label>
      </div>
    </div>
  <div class="row">
   <div class="large-12 columns">
    <label>商品名
     <input type="text" name="name" id="name" value="" required>
    </label>
   </div>
  </div>
  <div class="row">
   <div class="large-12 columns">
    <div class="row collapse">
     <label>価格</label>
     <div class="large-8 small-8 columns">
      <input type="text" name="price" id="price" value="" required>
     </div>
    </div>
   </div>
  </div>
  <div class="row">
   <div class="large-12 columns">
    <label>
     <input type="submit" class="button expand" name="submit" value="変更">
    </label>
   </div>
  </div>
 </form>
 <a class="close-reveal-modal" aria-label="Close">&#215;</a>
</div>

今回Modalウィンドウを開くときのボタンを押した場合、ページはリロードされないので、非同期処理Ajaxを用いて値を渡す必要がある。
ラジオボックスが選ばれてsubmitされた場合Modalウィンドウを開くようにしている。
modal.jsを示す。

$(function(){
    $('#modal').submit(function(event){
        event.preventDefault();
        var f = $(this);
        $.ajax({
            url: f.prop('action'),
            type: f.prop('method'),
            data: f.serialize(),
            timeout: 10000,
            dataType: 'json'
        })
        .done(function( data ) {
            // 通信が成功したときの処理
			$('#hoge').foundation('reveal', 'open');
			var radio_id = parseInt(data[0]) + 1;
			$('#p_id').val(data[radio_id]["id"]);
			$('#name').val(data[radio_id]["name"]);
			$('#price').val(data[radio_id]["price"]);
        })
        .fail(function( data ) {
            // 通信が失敗したときの処理
        })
        .always(function( data ) {
            // 通信が完了したとき
        });
    });
});

ここで、modal.jsの説明をする。
f.prop('action')は、formタグのaction属性からURLを受け取り、Ajaxのurlにセットしている。
これは、urlからデータを受け取るということを意味している。
次に、CSSフレームワークのfoundationのmodalのページに、jQueryを用いてmodalウィンドウを開くやり方が表記されている。
それによると、
$('#hoge').foundation('reveal', 'open');
で、開くことが出来るため、json.phpから値を受け取った時だけmodalを開くようにしている。
後は、適当に好きなように書いてください(笑)

次に、非同期で値を渡す先であるjson.phpを示す。

<?php
	/*
	DB接続,切断 insert,fetch,deleteの機能がsql.phpに備わっている。
	*/
	require_once("../sql.php");
	$conn = new MySQL("","","","");
	if(isset($_POST["radio"])){	
		$radio = $_POST["radio"];
		//今テーブルhogeに登録されてるデータ
		$query = "select * from hoge;";
		$row = $conn->fetch($query);
		array_unshift($row,$radio);
		$json_data = json_encode($row);
		echo trim($json_data);
	}
?>

json.phpでは、受け取ったラジオボタンの位置を受け取り、受け取ったデータとDBからのクエリの結果を連結してAjaxの.doneにデータを受け渡すものである。
ここでsql.phpは著者が適当に作成したMySQLの操作のためのクラスなので、適当に受け流してください。
json.phpラジオボタンの場所、DBに入っていたデータを表示している。
Ajaxは、表示しているデータをjsonで受け取り、処理を行っている。

とりあえず、こんな感じです。

参照は、いろいろだけどここらかな
foundation.zurb.com
chaika.hatenablog.com

TDU CTF 2014 Satellite in ConoHaに参加してきました。

今日は、TDU CTFに参加してきました。

ちょっと所要で、関東の方に来る予定があったため、うまいこと時間が合い参加できるようになったため参加しました。

前回ctf4bに参加して、楽しかったので、参加させていただきました。

 

で!今回は初心者がメイン!ということで、ある程度とけるかなぁー?wktkと思って参加したのですが、真の初心者にとっては、本当に難しくて大変でした。

 

とりあえず、ミニクイズの2問は解けたのですが、ほかで解けたのがSQLiの最初の問題とWireSharkを用いて、パケットを解析するものでした。

他は解けてないと思います。

 

問題を解いていて思ったのが、バイナリの問題で、ファイルの種類を判定するコマンドを持ってきたPCに入れていなかったということがきつくて、何も解けずにいました。

IDE demoも使い方忘れていたりと、まだまだだなぁと感じました。

 

解けなかったのですが、一番楽しいというかこのやろ!!って思った問題が、「起きてますか?」という問題で、パケットの内容をのんびり1つずつ見ていて、いつかflagがあるのかと思ってたら、そんなわけないでしょうというコメントがあったり、途中でyoutubeのURLで修造が出てきたりと遊び心が見えました。(笑)

 

まぁ最終的に270点しか取れませんでしたけど、周りがすごかったので、そういう人がいるということを実感することが出来てよかったです。

 

またこういう機会があれば参加してみたいです。

次は、予習して、ツールをある程度使えるようになってから頑張りたいと思います^-^v

connpass.com

Laravel4でのDataBaseの操作(INSERT,SELECT)とrouteの違う書き方

今回は、index.phpを違う方法で表示させました。

前回は、以下のように表示させましたが、


Route::get('/', function(){  
   return View::make('main.index');
});

 

今回は、このような感じです。

 

Route::get('/', 'HomeController@showWelcome');

 

意味としては、ルートは、HomeController.phpのshowWelcome関数を呼び出すことでindex.phpを表示させています。

 

---------------------------HomeController.php---------------------------------

class HomeController extends BaseController {

     function showWelcome(){

           return View::make('main.index');
     }
}

--------------------------------------------------------------------------------------

 

HomeController.phpは、/app/controllersに配置します。

 

次に、DB接続ですが、/app/config/database.phpで設定します。

ここでは、MySQLのところだけを表示させています。
-------------------------database.php---------------------------------

'mysql' => array(

'driver'    => 'mysql',

'host'      => 'localhost',

'database'  => 'hoge',

'username'  => '',

'password'  => '',

'charset'   => 'utf8',

'collation' => 'utf8_unicode_ci',

'prefix'    => '',

),
---------------------------------------------------------------------------

 

ここに、databaseには、DB名など。。。。まぁみたら分かりますよね。

 

こんな感じに、接続の設定は出来たらしいです。

 

次に、INSERTとSELECTで表示ですが、その関数をまとめた/app/controllers/PostController.phpを下に示します。

--------------------------------------PostController.php------------------------------------------

class PostController extends BaseController{

   function store(){

      DB::table('hoge')->insert([

         'subject'=>Input::get('subject'),

         'grade'=>Input::get('grade'),

         'category'=>Input::get('category'),

         'title'=>Input::get('title'),

         'content'=>Input::get('content')

      ]);

       return Redirect::to('/');

   }

   function index(){

       $posts = DB::table('hoge')->get();

       return View::make('main.index')->with('data',$posts);

   }

}
-------------------------------------------------------------------------------------------------------

 

insertがstore関数に当たり、selectに当たるのがindex関数です。

 

insertの書き方は、insert([//ここには配列]);

'カラム名'=>Input::get('htmlでのname属性')  

って感じです。

insertした後は、ルートディレクトリに戻りたいので、リダイレクトでルートに飛ばします。

 

index関数では、DB::table('DBでのテーブルの名前')->get(); でテーブルのデータを貰って、

 

return View::make('main.index')->with('data',$posts);

でmainフォルダのindex.phpファイルに、dataという変数で値$postsを渡すという意味になります。

 

そんな感じに、index.phpでは、$dataには、SQLのクエリの結果が入っています。

 

最後にroute.php

 

// 実際にDBにデータを入れる

Route::post('/', 'PostController@store');

// すべてのPostを表示する

Route::get('/', 'PostController@index');

 

と書くと、ルートで出力できると思います。

 

index.phpで変数dataをどのようにするかというと、

 

<?php foreach($data as $post){ ?>

 

<?php echo $post->subject." , " ?>

<?php echo $post->grade." , " ?>

<?php echo $post->category." , " ?>

<?php echo $post->title." , " ?>

<?php echo $post->content ?>

 

<?php } ?>

という感じで出力しました。