新卒から文系エンジニア→人材業界に転職した人のブログ

新卒から文系エンジニア→人材業界に転職。技術・スキルがないためブログを通して勉強。その後、IT業界の業界知識が活かせる人材業界へ。異業種×異職種の転職経験有り。

このエントリーをはてなブックマークに追加

【php・Ajax・mysql】Webtodoリスト完成~はじめてjs・php・Ajax・mysqlを連携させ、わかったこと・わからなかったこと~

【今回の紹介】


簡易なWebアプリを作ってみたいということから、

Webtodoリストを作成しました。


その振り返りとメモを兼ねて紹介します。

【内容】

■当初の目的


①Webアプリ作成の全体像をつかむ

①-①汎用的な機能(登録・変更・削除・検索)を作成してみる

①-②なんらかのデータをDBと連携するという流れをつかむ



Ajaxの活用の幅を広げたい

②-①DBと連携した時にどのようなPGの組み方になるのか

②-②他言語との連携してみたい

■実績


①Webアプリ作成の全体像をつかむ

→定性的だけど、なんとなくつかめた

①-①汎用的な機能(登録・変更・削除・検索)を作成してみる

     →すべての機能実装完了

①-②なんらかのデータをDBと連携するという流れをつかむ

     →追加したリスト情報をDBと連携完了

Ajaxの活用の幅を広げたい

②-①DBと連携した時にどのようなPGの組み方になるのか

AjaxphpmysqlxmlAjaxと言う流れを実感

  ②-②他言語との連携してみたい

phpと連携


■わかったこと

AjaxとDB連携の流れ

AjaxphpmysqlxmlAjax

②同一ページ内でいろいろできる(登録・変更・削除・検索)

→送信ボタンを押して画面遷移してというのはいらない。

 追加ボタンや追加したリスト名をダブルクリックすれば、

 裏でAjaxがはしり、DBへの登録が行うことができる

 また、DBからの値をうけとり、
     
     画面上ではjavascriptが動的に表示を行う事もできる


 
③当たり前だけど、HTTP通信がステートレスな通信であることを痛感

→当然DBからの登録処理・読み込み処理が実装されなければ、

 javascriptでいくら動的にリストを追加しても、更新(F5)を

 押せば、入力情報はなくなる。

だからHTTP通信でデータを保存するには、

①ブラウザのキャッシュを使用したセッション管理

②DBとの連携

③外部ファイルへの書き込み・読み込み

というような手段をとることが整理できた。
※ちなみに今回は②を使用した


■わからなかったこと


ajaxとDB連携の流れの詳細の部分

     →具体的に言うと、xmlhttprequestによるpost後のphpからのレスポンスの受け取り方の部分。
 、
      phpからDB取得(レスポンス)をうまくうけとることができず、
  
      なくなくxmlに変換して受け取ったけど、
 
      本当にxmlに変換する方法しかないのか
 
      ちょっと調べたらJSONというものもあるようだし、、
  
      そこらへんがまだまだわからない部分なので要確認。


 
jqueryでどのくらい便利になるのかって部分

今回は、jqueryは使用しなかったけど(最初は自分の理解のために未使用にした)

やたら検索するとでてくる。というか、問題が起こった時の解決方法とかも、jquery

だとこうすればよいという形で、jqueryのみの解決法を記載する場合が多かった。

javascriptにも当初よりかは馴れてきたので、

今後は、jqueryにも手を伸ばす必要があるかもしれない。

PHPでなにができるか。

PHP自体を学習したことがなく、

・セッション管理

・dbとの連携

する印象しかない。

サーバサイドの言語としてもっといろいろできるのかなー

と思いながら、、、でした





【参考ソース】

メイン画面(css

li{
	list-style-type:decimal;
	font-weight:bolder;
	margin-top:0.5em;
	margin-left:0.5em;
}
#input{
	margin-top:2em;	
		
	height:40%;
	border-bottom:2px #000000 solid;
				
}

#serch{
float:left;

}

	
#frame_toDo{
	float:left;
	height:90%;
	width:30%;
	border-right:2px #000000 solid;
	}
	
#frame_Doing{
	float:left;
	height:90%;
	width:30%;
	border-right:2px #000000 solid;
	}

#frame_Done{
	float:left;
	height:90%;
	width:30%;
	}

メイン画面


<!--//////////////////////////////
//↓画面デザイン部分//////////////
////////////////////////////////-->

<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div id="input">

    <h3>追加</h3>
    <select onChange="select_option=this.options[this.selectedIndex].innerHTML">
    	<option></option>
    	<option value="hight"> 優先度 高</option>
    	<option value="nomal"> 優先度 中</option>
    	<option value="low"> 優先度 低</option>
    </select>
	<input type="text" value="" id="add_text">
	<input type="button" value="追加" id="button" onclick="add_list()">
	
		<div id="serch">
			<h3>検索</h3>
				<select onChange="serch_input(select_serch=this.options[this.selectedIndex].innerHTML)">
    				<option></option>
    				<option value="doing_t">実行中タスク</option>
    				<option value="done_t">完了タスク</option>
    				</select>
		</div>
		<div id="serch_result">
		</div>
</div>

<div id="frame_toDo">
	<h1 id="h1_ToDo" onDblClick="allDel_li(this)">To Do</h1>
	<ul id="ul_toDo"></ul>
</div>

<div id="frame_Doing">
	<h1 id="h1_Doing" onDblClick="allDel_li(this)";>Doing</h1>
	<ul id="ul_Doing"></ul>
</div>

<div id="frame_Done">
	<h1 id="h1_Done" onDblClick="allDel_li(this)">Done</h1>
	<ul id="ul_Done"></ul>
</div>


<!--//////////////////////////////
//↑画面デザイン部分//////////////
////////////////////////////////-->



<?php
/*//////////////////////////////
//↓php・javascript処理部分//
////////////////////////////////*/



/*//////////////////////////////
//レコードが存在するか判定処理//
////////////////////////////////*/


$mysqli=new mysqli('localhost','sa','qwertyuiop@1','db_01');

	if($mysqli->connect_error){echo "DB接続できませーん";}
		$stmt=$mysqli->prepare("SET NAMES utf8");

$stmt->execute();
$stmt=$mysqli->prepare("select id from t_01 order by id desc limit 1 ") or exit("error");
$stmt->execute();
$stmt->bind_result($result_lastid);
$stmt->fetch();
$last_id=$result_lastid;
$last_id=$last_id+1;
?>

<?php
echo <<<EOM
<script Language="JavaScript" type="text/javascript">

var count=1;
var index=$last_id;
var index_cheak=/[0-9]/;
if(index_cheak.test(index)==true){count=$last_id;}


/*//////////////////////////////
/////////読み込み処理///////////
////////////////////////////////*/
window.onload=d_road;

function  d_road(){
	var url="d_load.php";
	var httpobj =createHttpRequest();
	httpobj.onreadystatechange = function() {
  		if (httpobj.readyState == 4) {
  			alert(httpobj.statusText);
  			result_value=httpobj.responseXML;

<!--DB取得データをdomに流し込む処理に渡す-->
  			d_load_output(result_value);
  			}
			};

		httpobj.open("POST",url);
		httpobj.setRequestHeader('Pragma', 'no-cache');
		httpobj.setRequestHeader('Cache-Control', 'no-cache');
		httpobj.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
		httpobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		httpobj.send(null);
}


/*////////////////////////////////////////
////DBから取得したxmlをDOMに流し込む処理//
////////////////////////////////////////*/
function d_load_output(xmldata){
	var nodelist=xmldata.getElementsByTagName('list');
		
		for(var i=0;i<nodelist.length;i++){
			var id=nodelist[i].childNodes[0].childNodes[0].nodeValue;
			var name=nodelist[i].childNodes[1].childNodes[0].nodeValue;
			var category=nodelist[i].childNodes[2].childNodes[0].nodeValue;
			var list_text=document.createTextNode(name);
			var new_list=document.createElement("li");
			new_list.appendChild(list_text);
			new_list.id=id;
			new_list.setAttribute("onDblClick","moveList(this)");
			new_list.setAttribute("onmouseover","addcolor(this)");
			new_list.setAttribute("onmouseout","defaultcolor(this)");;
			
			switch(category){
			
				case "frame_toDo":
					document.getElementById("ul_toDo").appendChild(new_list);
					break;
			
				case "frame_Doing":
					document.getElementById("ul_Doing").appendChild(new_list);
					break;
			
				case "frame_Done":
					document.getElementById("ul_Done").appendChild(new_list);
					break;
			}
		}
}


/*//////////////////////////////
/////////検索処理///////////////
////////////////////////////////*/

function serch_input(val){
    var result_value="";
	var send_value1=val;
	var url="serch.php";
	var httpobj =createHttpRequest();
	httpobj.onreadystatechange = function() {
  		if (httpobj.readyState == 4) {
  			alert(httpobj.statusText);
  			result_value=httpobj.responseXML;
  			serch_output(result_value);
  			}
			};

		httpobj.open("POST",url);
		httpobj.setRequestHeader('Pragma', 'no-cache');
		httpobj.setRequestHeader('Cache-Control', 'no-cache');
		httpobj.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
		httpobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		httpobj.send("send_value="+send_value1);
		
		
}

function serch_output(xmldate){

var div_serch_result=document.getElementById("serch_result");

if(div_serch_result.hasChildNodes){
		div_serch_result.removeChild(div_serch_result.firstChild);
}
var table=document.createElement("table");
var tbody=document.createElement("tbody");

var nodelist=xmldate.getElementsByTagName('list');

	for(var i=0;i<nodelist.length;i++){
	var row=document.createElement("tr");
	
<!--DB取得データをテーブルobjに流し込む処理-->
		for(var k=0;k<4;k++){
			var cell=document.createElement("td");
			cell.innerHTML=nodelist[i].childNodes[k].childNodes[0].nodeValue;
			row.appendChild(cell);
		}
		tbody.appendChild(row);
	}
	table.appendChild(tbody);
	table.border=1;
	document.getElementById("serch_result").appendChild(table);
}




/*//////////////////////////////
/////////リスト追加処理///////////
////////////////////////////////*/

function add_list(){
    var add_priority="("+select_option+")";
	var add_text=document.getElementById("add_text").value;
	var list_text=document.createTextNode(add_text+add_priority);
	var new_list=document.createElement("li");
	new_list.appendChild(list_text);
	new_list.id=count;  /*"new_list"+*/
	new_list.setAttribute("onDblClick","moveList(this)");
	new_list.setAttribute("onmouseover","addcolor(this)");
	new_list.setAttribute("onmouseout","defaultcolor(this)");
	document.getElementById("ul_toDo").appendChild(new_list);
	send_db(new_list.id);
	count++;
}



/*//////////////////////////////
/////////リスト移動処理///////////
////////////////////////////////*/

function moveList(obj){
	var ul_toDo=document.getElementById("ul_toDo");
	var ul_Doing=document.getElementById("ul_Doing");
	var ul_Done=document.getElementById("ul_Done");

<!--どのカテゴリ(todo or doing or done)にあるリストか判定する処理-->
	if("frame_toDo"==obj.parentNode.parentNode.id){
		var clone=obj.cloneNode(true);
		ul_Doing.appendChild(clone);
		ul_toDo.removeChild(obj);
		send_db(clone.id);
		
	}
		else if("frame_Doing"==obj.parentNode.parentNode.id){
			var clone=obj.cloneNode(true);
			ul_Done.appendChild(clone);
			ul_Doing.removeChild(obj);
			send_db(clone.id);
		}
			else{
			send_db(obj.id);
			ul_Done.removeChild(obj);
			
			}
}

/*//////////////////////////////
///////リスト強調表示処理/////
////////////////////////////////*/

function addcolor(obj){
	obj.style.color="#ff0000";
}

function defaultcolor(obj){
	obj.style.color="#000000";
}
<!--カテゴリー名(todo or doing or done)をダブルクリックすると配下の全リストを削除する処理-->
function allDel_li(obj){
	var allDel_ul=obj.nextSibling.nextSibling;
	var allDel_li=obj.nextSibling.nextSibling.childNodes;
		for(var i=allDel_li.length-1;i>=0;i--){
			allDel_ul.removeChild(allDel_li[i]);
		}
}


/*/////////////////////////////////
//DB処理(登録・変更・削除処理)///
//移動後の親ノードIDにより処理分岐//
//////////////////////////////////*/


function send_db(obj_id){

		/*共通処理(obj.objのID.objのカテゴリの取得)*/
		var obj=document.getElementById(obj_id);
		var obj_ParentId=obj.parentNode.parentNode.id;
		var send_text1=encodeURIComponent(obj_id);
		var send_text2=encodeURIComponent(document.getElementById(obj_id).firstChild.nodeValue);
		var send_text3=encodeURIComponent(obj.parentNode.parentNode.id);
		switch(obj_ParentId){
				
				/*移動後の親nodeIdが"frame_toDo"ならば登録処理*/
				case "frame_toDo":
					send_value=send_text1+","+send_text2+","+send_text3;
					var url="insert_db.php";
					var httpobj =createHttpRequest();
					httpobj.onreadystatechange = function() {
  						if (httpobj.readyState == 4) {
    						alert(httpobj.statusText);
  						}
					};
					httpobj.open("POST",url);
					httpobj.setRequestHeader('Pragma', 'no-cache');
					httpobj.setRequestHeader('Cache-Control', 'no-cache');
					httpobj.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
					httpobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
					httpobj.send("send_value="+send_value);
					break;
				
				/*移動後の親nodeIdが"frame_Doing"ならば変更処理*/
				case "frame_Doing":
				send_value=send_text1+","+send_text2+","+send_text3;
					var url="update_db.php";
					var httpobj =createHttpRequest();
					httpobj.onreadystatechange = function() {
  						if (httpobj.readyState == 4) {
    						alert(httpobj.statusText);
  						}
					};
					httpobj.open("POST",url);
					httpobj.setRequestHeader('Pragma', 'no-cache');
					httpobj.setRequestHeader('Cache-Control', 'no-cache');
					httpobj.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
					httpobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
					httpobj.send("send_value="+send_value);
					break;
				
				/*移動後の親nodeIdが"frame_Done"ならば変更または削除処理*/
				case "frame_Done":
				send_value=send_text1+","+send_text2+","+send_text3;
					var url="update_db.php";
					var httpobj =createHttpRequest();
					httpobj.onreadystatechange = function() {
  						if (httpobj.readyState == 4) {
    						alert(httpobj.statusText);
  						}
					};
					httpobj.open("POST",url);
					httpobj.setRequestHeader('Pragma', 'no-cache');
					httpobj.setRequestHeader('Cache-Control', 'no-cache');
					httpobj.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
					httpobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
					httpobj.send("send_value="+send_value);
				break;
				
				
			}
	}


/*//////////////////////////////
//xmlhttprequestobjの生成処理///
////////////////////////////////*/

<!--xmlhttprequestobjの生成-->
function createHttpRequest(){
	try{
			return new XMLHttpRequest();
		}catch(e){}
		try{
			return new ActiveXObject('MSXML2.XMLHTTP.6.0');
		}catch(e){}
		try{
			return new ActiveXObject('MSXML2.XMLHTTP.3.0');
		}catch(e){}
		try{
			return new ActiveXObject('MSXML2.XMLHTTP');
		}catch(e){}
	
		return null;
	}

</script>
EOM
?>

</body>
</html>

登録処理

<?php
  header('Content-Type: text/html; charset=UTF-8');
    $input=$_POST['send_value'];
    $inputs=explode(",",$input);
    $time=date("Y-m-d H:i:s");
    $mysqli=new mysqli('localhost','sa','qwertyuiop@1','db_01');
		if($mysqli->connect_error){echo "DB接続できませーん";}
	$stmt=$mysqli->prepare("SET NAMES utf8");
	$stmt->execute();
	
	$stmt=$mysqli->prepare("insert into t_01 values('$inputs[0]','$inputs[1]','$inputs[2]','0','$time')") or exit("error");
	$stmt->execute();
	$mysqli->close();

?>

変更処理

<?php
  header('Content-Type: text/html; charset=UTF-8');
    $input=$_POST['send_value'];
    $inputs=explode(",",$input);
    $time=date("Y-m-d H:i:s");
     $mysqli=new mysqli('localhost','sa','qwertyuiop@1','db_01');
		if($mysqli->connect_error){echo "DB接続できませーん";}
	$stmt=$mysqli->prepare("SET NAMES utf8");
	$stmt->execute();
	$stmt=$mysqli->prepare("select category from t_01 where id='$inputs[0]'") or exit("セレクト文失敗");
	$stmt->execute();
	$stmt->bind_result($result_category);
	$stmt->fetch();
	$mysqli->close();
	if($result_category=='frame_toDo' || $result_category=='frame_Doing'){
	$mysqli=new mysqli('localhost','sa','qwertyuiop@1','db_01');
		if($mysqli->connect_error){echo "DB接続できませーん";}
	$stmt=$mysqli->prepare("SET NAMES utf8");
	$stmt->execute();
	$stmt=$mysqli->prepare("update  t_01 set category='$inputs[2]',update_time='$time' where id='$inputs[0]'") or exit("変更文に問題ありー");
	$stmt->execute();
	$mysqli->close();
	}else{
	$mysqli=new mysqli('localhost','sa','qwertyuiop@1','db_01');
		if($mysqli->connect_error){echo "DB接続できませーん";}
	$stmt=$mysqli->prepare("SET NAMES utf8");
	$stmt->execute();
	$stmt=$mysqli->prepare("update  t_01 set delflg='1' where id='$inputs[0]'") or exit("削除分に問題ありー");
	$stmt->execute();
	$mysqli->close();
	
	}
	
	
?>

検索処理

<?php
header('Content-Type: text/html; charset=UTF-8');
	/*検索条件の取得*/
	$value=$_POST['send_value'];
	/**/
	$mysqli=new mysqli('localhost','sa','qwertyuiop@1','db_01');
		if($mysqli->connect_error){echo "DB接続できませーん";}
	$stmt=$mysqli->prepare("SET NAMES utf8");
	$stmt->execute();
	
	/*検索条件の取得による分岐*/
		
		if($value=="実行中タスク")
			$stmt=$mysqli->prepare("select id,name,category,update_time from t_01 where delflg=0 ") or exit("error");
		else{
			$stmt=$mysqli->prepare("select id,name,category,update_time from t_01 where delflg=1 ") or exit("error");
		}
	
	$stmt->execute();
	$stmt->bind_result($result_id,$result_name,$result_category,$result_time);


/*/////////////////////////////
//DB取得データをxmlデータに変換//
////////////////////////////////*/
	
header("Content-type: text/xml");
	echo'<?xml version="1.0" encoding="utf-8" ?>';
	echo '<lists>';
		while($stmt->fetch()){
			echo '<list>';
			echo '<id>'.$result_id.'</id>';
			echo '<name>'.$result_name.'</name>';
			echo '<category>'.$result_category.'</category>';
			echo '<updatetime>'.$result_time.'</updatetime>';
			echo '</list>';
		}
	echo '</lists>';
?>

読み込み処理

<?php
header('Content-Type: text/html; charset=UTF-8');
$value=$_POST['send_value'];

 $mysqli=new mysqli('localhost','sa','qwertyuiop@1','db_01');
		if($mysqli->connect_error){echo "DB接続できませーん";}
	$stmt=$mysqli->prepare("SET NAMES utf8");
	$stmt->execute();
	$stmt=$mysqli->prepare("select id,name,category from t_01 where delflg=0 ") or exit("error");
	$stmt->execute();
	$stmt->bind_result($result_id,$result_name,$result_category);


/*//////////////////////////////
//DB取得データをxmlデータに変換//
////////////////////////////////*/


	header("Content-type: text/xml");
	echo'<?xml version="1.0" encoding="utf-8" ?>';
	echo '<lists>';
		while($stmt->fetch()){
			echo '<list>';
			echo '<id>'.$result_id.'</id>';
			echo '<name>'.$result_name.'</name>';
			echo '<category>'.$result_category.'</category>';
			echo '</list>';
		}
	echo '</lists>';
?>
.hatena-module:nth-of-type(10) { background: transparent; } .hatena-module:nth-of-type(10) .hatena-module-title{ display: none; } .hatena-module:nth-of-type(10) .hatena-module-body { padding: 0; }