【PHP】GETで送信する文字列に”.”(ドット)が含まれる場合の対策

$_GETで送信する文字列に”.”(ドット)が含まれる場合、PHP は“.”(ドット)“_”(アンダースコア)に自動的に変換します。
その為、GETメソッドで値を受け取ろうとすると文字列が”_”(アンダースコア)に変換されたまま受け取る事になる。
例)
ore-memo.com

ore-memo_com

php.iniファイルのregister_globalsをoffにするなどの対応もできますが、php.iniファイルや.htaccessファイルはいつでも変更できるわけではないので、PHPファイル内で対応してみた。

【解決方法】
サーバ変数、
$_SERVER['QUERY_STRING']
で取得できるデータから、欲しい文字列を抜き取る方法で解決できた。

例)
http://www.ore-memo.com/index.html?url=ore-memo.com
の場合、

	// サーバ変数の中身をexplodeで分割し配列に入れる
	$get_data = explode("=", $_SERVER['QUERY_STRING']);
	
	// 特殊文字を元に戻す
	echo urldecode($get_data[0])."<br />";
	echo urldecode($get_data[1]);

サーバ変数$_SERVER['QUERY_STRING']の中には”?”以降の文字列が入る為、”=”で分割して値を取り出す必要がある。

【出力結果】

url
ore-memo.com

GETメソッドで複数の値を受け取る場合は、”&”で分割したのち、”=”で再度分割する。

【Android】画像を画面サイズに合わせて表示する(マルチデバイス対応)

画像を複数デバイスの画面サイズに合わせて表示しマルチデバイスに対応したい。

Androidデバイスは画面サイズやアスペクト比がさまざまで、基準が決めにくい為、
iphone3G(320×480px)やiphone4(640×960px)の画像解像度のアスペクト比2:3を基準にする。

■仕様■
・準備する画像はすべてアスペクト比2:3とする。
・画面表示は横幅を基準とし、横幅いっぱいに表示する。
・ほとんどの機種で高さが少し短くなるので、画像を中央に配置し、余白(背景)は黒にする。
・現行機種でアスペクト比2:3よりも高さが小さいものはない様なので、このタイプは対応しない事とする。

【ImageResizeView.java】(マルチデバイス対応画像リサイズクラス)

public class ImageResizeView extends View{
	
	private Bitmap bmp;
	private int dp_w;
	private int dp_h;
	private int drow_h;
	private int drow_s;
	
	public ImageResizeView(Context context, int resource_name){
		super(context);
		// リソースからbitmapを作成
		bmp = BitmapFactory.decodeResource(context.getResources(), resource_name);
		// WindowManager取得
		WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
		// Displayインスタンス生成
		Display dp = wm.getDefaultDisplay();
		// ディスプレイサイズ取得
		dp_w = dp.getWidth();
		dp_h = dp.getHeight();
		// リサイズ画像の高さ
		drow_h = (dp_w / 2) * 3;
		// 描画始点の高さ
		drow_s = (dp_h - drow_h) / 2;
	}

	@Override
	protected void onDraw(Canvas canvas){
		// 背景色
		canvas.drawColor(Color.BLACK);
		// イメージ画像リサイズ
		bmp = Bitmap.createScaledBitmap(bmp, dp_w, drow_h , true);  
		// 描画
		canvas.drawBitmap(bmp, 0, drow_s, null);
	}
}

Viewクラスを継承して、onDrawメソッドをオーバーライドしてcanvasに描画する。

【Activity000.java】(Activityクラス)

public class Activity000 extends Activity {

	// リソースファイル名
	int resource_name = R.drawable.img00;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
		setContentView(new ImageSizePut(this, resource_name));
	}
}

【出力結果】
画像マルチデバイス対応

【Android】リソースの画像サイズを取得する

リソースの画像サイズを取得してみる。

今回は、複数のActivityから利用したいので、別クラスを作成する。
Activityでインスタンスを生成して、リソースの画像を指定し、その画像サイズを受け取る。

【ImageSizeGet.java】

public class ImageSizeGet{

	// 画像のサイズを取得するメソッド
	public String getSize(Context context, int resource_name){
		// リソースからbitmapを作成
		Bitmap image = BitmapFactory.decodeResource(context.getResources(), resource_name);
		
		// 画像サイズ取得
		int width  = image.getWidth();
		int height = image.getHeight();
		
		// 画像サイズの文字列を返す
		String size = "w:" + width + ",h:" + height;
		return size;
	}
}

Context : アプリケーションの環境情報をグローバル(AndroidOSの全域)に受け渡しするためのインターフェース

【Activity000.java】

public class Activity000 extends Activity {

	// リソースファイル名を指定
	int resource_name = R.drawable.img01;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		// ImageSizeGetクラスをインスタンス化する
		ImageSizeGet put_text = new ImageSizeGet();
		
		// ImageSizeGetのgetNameメソッドを呼び出す
		String size = put_text.getSize(this, resource_name);

		// TextViewを準備
		TextView tv = new TextView(this);
		
		// テキスト出力
		tv.setText(size);
		setContentView(tv);
	}
}

Activityからメソッドを呼ぶ時に渡す引数Contextには、Activity自身を指すthisを指定する

【出力結果】

w:横幅,h:高さ

【PHP】POSTのデータを配列に代入する

フォームで送信した値をPOSTで受け取って、配列に代入してみる。

POSTのデータを配列に代入

【post.html】

<?php
	// 初期値設定
	$errer_message[] = ""; // エラーメッセージ配列
	$errer_no = 0; // ループ用エラーナンバー

	foreach($_POST as $key => $val){
		// データを配列に代入
		$data_arr[$key] = $val;
	}

	// 代入した配列の中身を確認
	print_r($data_arr);
?>

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>POSTのデータを配列に代入</title>
</head>
<body>
<div>
	<form method="POST" action="post.html">
		データ1:<input type="text" name="DATA1"><br/ >
		データ2:<input type="text" name="DATA2"><br/ >
		データ3:<input type="text" name="DATA3"><br/ >
		データ4:<input type="text" name="DATA4"><br/ >
		<input type="submit" value="送信">
		<input type="reset" value="取消">
	</form>
</div>
</body>
</html>

【出力結果】

Array ( [DATA1] => 東京都 [DATA2] => 神奈川県 [DATA3] => 千葉県 [DATA4] => 埼玉県 )

【JavaScript】読み込む外部CSSを動的に変える

JSで読み込む外部CSSを動的に変える

今回は、表示ボタンを押したときに入力するパスワードによって、
呼び出すCSSを変更して、表示する内容を変えるスクリプトを作ってみた。

■仕様■
・初期設定でBOXを非表示(display: none;)にしておく。
・「表示ボタン」を押したらダイアログを立ち上げ、パスワードを要求する。
・入力されたパスワードによって表示するCSSを変える。
 (パスワード「password01」→secret01.css、「password02」→secret02.cssを表示)
・display: none;→display: block;とする事で表示するBOXをコントロールする。
・パスワードが違う場合はダイアログ内に”パスワードが違います!” を表示する。

■処理の手順■
①表示ボタンが押されたら、passPrompt()関数が起動。
②入力できるダイアログを表示するprompt()が起動し、パスワードを要求。
③ダイアログのフォームに入力されたパスワードによって処理を変える。
④パスワードが一致したらcreateElement()、setAttribute()でlinkタグ、要素を生成する。
⑤getElementsByTagName()で指定要素内(headタグ)に子要素(linkタグ)を追加する。

【index.html】

<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>JavaScriptパスワードテスト</title>
<link rel="stylesheet" href="css/common.css" type="text/css">

<script language="JavaScript"><!--
function passPrompt() {	
	myPassWord = window.prompt("パスワードを入力してください","");
	if(myPassWord == "password01"){
		// linkタグと要素を生成
		var css=document.createElement("link");
		css.setAttribute("rel","stylesheet");
		css.setAttribute("type","text/css");
		css.setAttribute("href","css/secret01.css");
		// 指定要素内(headタグ)に子要素(linkタグ)を追加
		document.getElementsByTagName("head")[0].appendChild(css);
	}else if(myPassWord == "password02"){
		var css=document.createElement("link");
		css.setAttribute("rel","stylesheet");
		css.setAttribute("type","text/css");
		css.setAttribute("href","css/secret02.css");
		document.getElementsByTagName("head")[0].appendChild(css);
	}else{
		alert( "パスワードが違います!" );
	}
}
// --></script>

</head>
<body>
<div id="container">
	<p class="pw"><a onClick="passPrompt()">表示ボタン</a></p>
	<ul>
		<li class="secret00">通常BOX</li>
		<li class="secret01">秘密BOX01</li><!-- "password01"で表示 -->
		<li class="secret02">秘密BOX02</li><!-- "password02"で表示 -->
	</ul>
	<a href="index.html">←戻る</a>
</div>
</body>
</html>

【common.css】(レイアウト用)

*{
	margin: 0;
	padding: 0;
}

#container {
	width: 300px;
	text-align: center;
	margin: auto;
	padding: 10px;
}

p.pw a{
	display: block;
	width: 160px;
	height: 42px;
	line-height: 42px;
	margin: auto;
	color: #FFFFFF;
	background: #000000;
}

li{
	display: block;
	width: 160px;
	height: 42px;
	line-height: 42px;
	border: 1px solid #000000;
	margin: 3px auto;
}

li.secret01,
li.secret02 {
	display: none;
}

【secret01.css】(表示切り替え用)

li.secret01 {
	display: block;
}

【secret02.css】(表示切り替え用)

li.secret02 {
	display: block;
}

【実行結果】
読み込むCSSを動的に変えるJS

【Android】SurfaceViewに対するタッチイベントで再描画する

SurfaceViewに対するイベント処理も、考え方は通常のViewでの処理とほとんどかわりません。

今回はSurfaceViewに描画した真顔のイラストをタッチ後、笑顔にする。

【準備画像】

SurfaceViewにタッチイベント

public class SampleSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
	
	// 表示する画像
	private Bitmap image01;
	private Bitmap image02;
	private Bitmap image03;
	private Bitmap image02b;
     
	// コンストラクタ
	public SampleSurfaceView4(Context context) {
		super(context);
         
		getHolder().addCallback(this);
		// Bitmapリソースを用意
		image01 = BitmapFactory.decodeResource(getResources(), R.drawable.face);
		image02 = BitmapFactory.decodeResource(getResources(), R.drawable.eye);
		image02b = BitmapFactory.decodeResource(getResources(), R.drawable.eye2);
		image03 = BitmapFactory.decodeResource(getResources(), R.drawable.mouth);
	}
     
	// SurfaceView生成時に呼び出される(初期画面の描画)
	public void surfaceCreated(SurfaceHolder holder) {
    	
		doDraw(holder);
	}
     
	// SurfaceView変更時に呼び出される(画面の更新処理)
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		// 処理がない場合も必要
	}
     
	// SurfaceView破棄時に呼び出される(画面の削除、削除後の処理)
	public void surfaceDestroyed(SurfaceHolder holder) {
		// 処理がない場合も必要
	}
    
	private void doDraw(SurfaceHolder holder) {
		// Canvas取得しロックする
		Canvas canvas = holder.lockCanvas();
		Paint paint = new Paint();
		//paint.setColor(Color.WHITE);
         
		// 描画処理
		canvas.drawBitmap(image01, 0, 0, paint);
		canvas.drawBitmap(image02, 0, 0, paint);
		canvas.drawBitmap(image03, 0, 0, paint);
         
		// LockしたCanvasを解放する
		holder.unlockCanvasAndPost(canvas);
	}
	
	private void onDraw(SurfaceHolder holder) {
		// Canvas取得しロックする
		Canvas canvas = holder.lockCanvas();
		Paint paint = new Paint();
		//paint.setColor(Color.WHITE);
         
		// 描画処理
		canvas.drawBitmap(image01, 0, 0, paint);
		canvas.drawBitmap(image02b, 0, 0, paint);
		canvas.drawBitmap(image03, 0, 0, paint);
         
		// LockしたCanvasを解放する
		holder.unlockCanvasAndPost(canvas);
	}
	
	// タッチイベント
	@Override
	public boolean onTouchEvent(MotionEvent event){
		onDraw(getHolder());
		return true;
	}
}

【実行結果】
SurfaceViewでオンタッチイベント

【Android】FrameLayout内でTextViewにマージンを指定する

前回、「FrameLayoutでSurfaceViewとTextViewと重ねて表示する」で作成したTextViewにマージンを指定する。
しかし、元となるレイアウトがFrameLayoutの場合、TextViewにmarginが設定できない。

FrameLayoutとTextViewの間にmarginが設定できるLinearLayoutを噛ませてやればうまくいく。

例)
FrameLayout -> TextView

FrameLayout -> LinearLayout -> TextView

【Activity000.java】

public class Activity000 extends Activity {

	// LayoutParamsにセットするパラメータを準備
	private final int FP = ViewGroup.LayoutParams.FILL_PARENT; 
	private final int WC = ViewGroup.LayoutParams.WRAP_CONTENT;
	private final int LFP = LinearLayout.LayoutParams.FILL_PARENT;
	private final int LWC = LinearLayout.LayoutParams.WRAP_CONTENT;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		// FrameLayoutを準備
		FrameLayout fl = new FrameLayout(this);
		setContentView(fl);
 
		// FrameLayoutにSurfaceViewをセットする
		fl.addView(new SampleSurfaceView2(this),new ViewGroup.LayoutParams(WC, WC));
        
		// SurfaceViewと重ねるTextViewを準備
		TextView tv = new TextView(this);
		tv.setText("SurfaceViewとTextViewを重ねる\nさらにTextViewにマージンを指定する");
		tv.setHeight(120);
		tv.setTextColor(Color.BLACK);
		tv.setBackgroundColor(Color.WHITE);
		
		// TextViewを入れるLinearLayoutを準備
		LinearLayout ll = new LinearLayout(this);
		LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LFP, LWC);
		lp.setMargins(10, 10, 10, 10);
		tv.setLayoutParams(lp);
		ll.addView(tv);
		
		// FrameLayoutにLinearLayoutをセットする
		fl.addView(ll, new ViewGroup.LayoutParams(FP, WC));
	}
}

setMarginsのパラメータ指定 : setMargins(左, 上, 右, 下)

【実行画面】

setMargins

【Android】画面サイズ(横幅/高さ)を取得する

アンドロイドデバイスは端末ごとに画面サイズがバラバラで、を考慮しながら開発する必要がある。
アプリケーションで端末の画面サイズを取得することにより、動的に画面デザインを構成することができる。

画面サイズなど、ディスプレイの情報を取得するには
android.viewパッケージのDisplayクラスを使用します。

【手順1】
WINDOW_SERVICEを指定したgetSystemServiceメソッドで、WindowManagerのインスタンスを取得する。
【手順2】
WindowManager.getDefaultDisplayメソッドで、Displayクラスのインスタンスを生成する。
【手順3】
Display.getWidth/getHeightメソッドで、画面サイズ(横幅/高さ)情報を取得する。

【Activity000.java】

public class Activity000 extends Activity {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// TextViewインスタンス生成
		TextView tv = new TextView(this);
		
		// WindowManager取得
		WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE);
		
		// Displayインスタンス生成
		Display dp = wm.getDefaultDisplay();

		String size = "Width = " + dp.getWidth() + "\n" + "Height = " + dp.getHeight();
		
		// テキスト出力
		tv.setText(size);
		setContentView(tv, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
	}
}

【出力結果】
Android画面サイズを取得

【Android】FrameLayoutでSurfaceViewとTextViewと重ねて表示する

前回、「SurfaceViewで複数画像を重ねて描画する」で作成したSurfaceViewとTextViewを重ねる。

FrameLayoutでSurfaceViewとTextViewを重ねる

今回は、複数のViewを重ね合わせて表示することができるFrameLayoutを使用する。

【Activity000.java】

public class Activity000 extends Activity {

	// LayoutParamsにセットするパラメータを準備
	private final int FP = ViewGroup.LayoutParams.FILL_PARENT; 
	private final int WC = ViewGroup.LayoutParams.WRAP_CONTENT;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		// FrameLayoutを準備
		FrameLayout fl = new FrameLayout(this);
		setContentView(fl);
 
		// FrameLayoutにSurfaceViewをセットする
		fl.addView(new TestSurfaceView(this),new ViewGroup.LayoutParams(WC, WC));
        
		// SurfaceViewと重ねるTextViewを準備
		TextView tv = new TextView(this);
		tv.setText("SurfaceViewとTextViewを重ねる");
		tv.setHeight(120);
		tv.setTextColor(Color.BLACK);
		tv.setBackgroundColor(Color.WHITE);
        
		// FrameLayoutにTextViewをセットする
		fl.addView(tv, new ViewGroup.LayoutParams(FP, WC));
	}
}

FrameLayoutはViewGroupでnewする事に注意!!

【実行結果】

SurfaceViewとTextViewを重ねる

念のため、前回のSurfaceView
【TestSurfaceView.java】

public class TestSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
	
	// 表示する画像
    private Bitmap image01;
    private Bitmap image02;
    private Bitmap image03;
     
    // コンストラクタ
    public TestSurfaceView(Context context) {
        super(context);
         
        getHolder().addCallback(this);
        // Bitmapリソースを用意
        image01 = BitmapFactory.decodeResource(getResources(), R.drawable.face);
        image02 = BitmapFactory.decodeResource(getResources(), R.drawable.eye);
        image03 = BitmapFactory.decodeResource(getResources(), R.drawable.mouth);
    }
     
    // SurfaceView生成時に呼び出される(初期画面の描画)
    public void surfaceCreated(SurfaceHolder holder) {
        // Canvas取得しロックする
        Canvas canvas = holder.lockCanvas();
        Paint paint = new Paint();
        paint.setColor(Color.WHITE);
         
        // 描画処理
        canvas.drawBitmap(image01, 0, 0, paint);
        canvas.drawBitmap(image02, 0, 0, paint);
        canvas.drawBitmap(image03, 0, 0, paint);
         
        // LockしたCanvasを解放する
        holder.unlockCanvasAndPost(canvas);
    }
     
    // SurfaceView変更時に呼び出される(画面の更新処理)
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // 処理がない場合も必要
    }
     
    // SurfaceView破棄時に呼び出される(画面の削除、削除後の処理)
    public void surfaceDestroyed(SurfaceHolder holder) {
        // 処理がない場合も必要
    }
}

【Android】SurfaceViewで複数画像を重ねて描画する

複数の画像をView上で重ねて表示したい

【準備画像】
準備画像パーツ

今回は、SurfaceViewをActivityとは別クラスで準備する。

【Activity000.java】

public class Activity000 extends Activity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		// SurfaceViewのインスタンスを生成してビューを追加する
		setContentView(new TestSurfaceView(this));
	}
}

SurfaceViewの実装する場合、SurfaceHolderをインターフェイスとして使う為、
描画用のコールバックを準備する必要がある。

■コンストラクタを含めた4つのメソッドを準備する
・SurfaceViewのコンストラクタ
・SurfaceHolder.Callback.surfaceCreated()
・SurfaceHolder.Callback.surfaceChanged()
・SurfaceHolder.Callback.surfaceDestroyed()

※コンストラクタ:クラスからオブジェクトを作成した際に、自動的に実行されるメソッドのこと

【TestSurfaceView.java】

public class TestSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
	// 表示する画像
	private Bitmap image01;
	private Bitmap image02;
	private Bitmap image03;
	
	// コンストラクタ
	public TestSurfaceView(Context context) {
		super(context);
		
		getHolder().addCallback(this);
		// Bitmapリソースを用意
		image01 = BitmapFactory.decodeResource(getResources(), R.drawable.face);
		image02 = BitmapFactory.decodeResource(getResources(), R.drawable.eye);
		image03 = BitmapFactory.decodeResource(getResources(), R.drawable.mouth);
	}
	
	// SurfaceView生成時に呼び出される(初期画面の描画)
	public void surfaceCreated(SurfaceHolder holder) {
		// Canvas取得しロックする
		Canvas canvas = holder.lockCanvas();
		Paint paint = new Paint();
		paint.setColor(Color.WHITE);
		
		// 描画処理
		canvas.drawBitmap(image01, 0, 0, paint);
		canvas.drawBitmap(image02, 0, 0, paint);
		canvas.drawBitmap(image03, 0, 0, paint);
		
		// LockしたCanvasを解放する
		holder.unlockCanvasAndPost(canvas);
	}
	
	// SurfaceView変更時に呼び出される(画面の更新処理)
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		// 処理がない場合も必要
	}
    
	// SurfaceView破棄時に呼び出される(画面の削除、削除後の処理)
	public void surfaceDestroyed(SurfaceHolder holder) {
		// 処理がない場合も必要
	}
}

【実行結果】
SurfaceViewで画像を重ねる