728x90

mysql 확장 기능은 마침내 PHP 7에서 제거되었다.
PHP는 급격하게 성장하며 더 나은 프로그래밍 언어가 되고 있다.
PDO를 사용하는 것은 객체지향과 재사용 가능한 애플리케이션의 데이터베이스 층을 만드는 첫단계이다.

PDO(PHP Data Objects)란 여러가지 데이터베이스를 제어하는 방법을 표준화시킨 것이다.
데이터베이스는 다양한 종류가 있다. PDO 를 사용하면 동일한 방법으로 데이터베이스를 제어할 수 있다.

 

PDO를 이용하기 위한 준비사항

윈도우 Autoset9 (Apache + PHP + MySQL) 에서 PDO를 이용하려면 php.ini 파일에서 주석처리된 것을 없앤다. extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
;extension=php_pdo_odbc.dll
extension=php_pdo_pgsql.dll
extension=php_pdo_sqlite.dll

 

Autoset9을 다시 실행하면 phpinfo() 에서 설치된 것을 확인할 수 있다.

 

PDO 를 이용하기 위한 준비가 되었다.

PHP 5.5 이상에서 이용 가능하다. AutoSet9 을 설치하면 PHP 5.6.0 버전을 이용한다.

CentOS 6.6 에서 APM 소스 설치방법으로 하는 방법도 가능하더라. 소스 설치 스크립트를 만들어 두면 편리하다.

 

PDO 기본 사용법

$variable = new PDO(DSN, 사용자명, PW);
$variable = null; // PDO 접속 종료
DSN : 접두사:host=localhost;dbname=DB명;charset=utf8;
접두사 : DB의 종류(MySQL, Pgsql, Sqlite)

 

=== dbinfo.php ===

<?php
$db['host'] = "localhost";
$db['name'] = "address";
$db['user'] = "address_root";
$db['pass'] = "autoset";
$db['port'] = "3306";

//use mysql;
//create user address_root@localhost identified by 'autoset';
//grant all privileges on address.* to address_root@localhost;  -- 사용자 권한 부여
//flush privileges;    -- // 변경된 내용을 메모리에 반영(권한 적용)
?>

 

객체 생성 : try catch 문에서 생성한다.

===  pdoconn.php ===

<?php
include_once 'dbinfo.php';
try{
    // MySQL PDO 객체 생성
    $dbconn = new PDO('mysql:host='.$db['host'].';dbname='.$db['name'].';charset=utf8', $db['user'], $db['pass']);

    // 에러 출력
    $dbconn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(Exception $e) {
    echo 'Failed to obtain database handle : '.$e->getMessage();
}
?>

 

new PDO DSN 입력할 때 실수하면 에러가 발생한다.

 

 

PDO SQL 실행

 

<?php
require_once 'pdoconn.php';
// SELECT
$sql="select uid,ItemName,Price,Quantity from table_items";
$stmt = $dbconn->prepare($sql);
$stmt->execute();

// Fetch 모드를 설정
$stmt->setFetchMode(PDO::FETCH_BOTH); // PDO::FETCH_ASSOC, PDO::FETCH_NUM
// 1 row 씩 가져오기
while($row= $stmt->fetch()) {
    echo $row[0].' | ';
    echo $row[1].' | ';
    echo $row[2].' | ';
    echo $row[3].'<br />';
}
?>

 

검색조건을 추가해보자.

위의 내용과 비교해서 달라진 점이 무엇인지 확인해보면

검색조건이 where ItemName=:ItemName 로 되어 있고, $stmt->bindParam(':ItemName', $ItemName); 한줄을 추가했고, 실제 검색어 Value 인 $ItemName ='사과'; 을 한줄 추가했다.

<?php
require_once 'pdoconn.php';
// SELECT
$sql="select uid,ItemName,Price,Quantity from table_items where ItemName=:ItemName";
$stmt = $dbconn->prepare($sql);
$stmt->bindParam(':ItemName', $ItemName); // 변수에 바인딩하기 위해 bindParam을 사용
$ItemName ='사과';
$stmt->execute();

// Fetch 모드를 설정 및 1 row 씩 가져오기
while($row= $stmt->fetch(PDO::FETCH_BOTH)) {
    echo $row[0].' | ';
    echo $row[1].' | ';
    echo $row[2].' | ';
    echo $row[3].'<br />';
}
?>
 

 

$stmt->bindValue(':id', '1', PDO::PARAM_STR);

$stmt->bindValue(':ItemName', '사과');

'1', '사과' 처럼 값을 직접 넣을 때는 bindValue 를 사용해야 한다.

 

$stmt->bindParam(':ItemName', '사과'); // bindParam 을 사용하면 에러가 발생한다.

 

 

이제 bindParam 과 bindValue 차이를 확인할 수 있는 예제를 한번 보자.

아래의 첫번째 예제는 '사과'에 대한 결과를 반환하고, 아래의 두번째 예제는 '복숭아'에 대한 결과를 반환한다.

<?php
require_once 'pdoconn.php';
// SELECT
$ItemName ='사과';
$sql="select uid,ItemName,Price,Quantity from table_items where ItemName=:ItemName";
$stmt = $dbconn->prepare($sql);
$stmt->bindValue(':ItemName', $ItemName); // 변수에 바인딩하기 위해 bindParam을 사용
$ItemName ='복숭아'; // 이건 실행안함. Value 로 이미 인식되어서 인듯....
$stmt->execute();

// Fetch 모드를 설정 및 1 row 씩 가져오기
while($row= $stmt->fetch(PDO::FETCH_BOTH)) {
    echo $row[0].' | ';
    echo $row[1].' | ';
    echo $row[2].' | ';
    echo $row[3].'<br />';
}
$dbconn = null; // DB접속 종료
?>

<?php
require_once 'pdoconn.php';
// SELECT
$ItemName ='사과';
$sql="select uid,ItemName,Price,Quantity from table_items where ItemName=:ItemName";
$stmt = $dbconn->prepare($sql);
$stmt->bindParam(':ItemName', $ItemName); // 변수에 바인딩하기 위해 bindParam을 사용
$ItemName ='복숭아';
$stmt->execute();

// Fetch 모드를 설정 및 1 row 씩 가져오기
while($row= $stmt->fetch(PDO::FETCH_BOTH)) {
    echo $row[0].' | ';
    echo $row[1].' | ';
    echo $row[2].' | ';
    echo $row[3].'<br />';
}
$dbconn = null;
?>

 

이렇게 실행해야 하는 경우가 있는지는 모르지만 결과는 두개를 반환한다.

<?php
require_once 'pdoconn.php';
// SELECT
$sql="select uid,ItemName,Price,Quantity from table_items where ItemName=:ItemName";
$stmt = $dbconn->prepare($sql);
$stmt->bindParam(':ItemName', $ItemName); // 변수에 바인딩하기 위해 bindParam을 사용
$ItemNames = array('사과','복숭아');
foreach($ItemNames as $ItemName){
    $stmt->execute();
    // Fetch 모드를 설정 및 1 row 씩 가져오기
    while($row= $stmt->fetch(PDO::FETCH_BOTH)) {
        echo $row[0].' | ';
        echo $row[1].' | ';
        echo $row[2].' | ';
        echo $row[3].'<br />';
    }
}
$dbconn = null;
?>

 

IN 으로 받은 걸 처리하는게 올바른 것인지 궁금하여 Stakoverflow 에서 검색하고 테스트 해본 결과를 적어둔다.

<?php
require_once 'pdoconn.php';
// SELECT
$ItemNames = array('사과','복숭아');
$total_items = count($ItemNames);
$question_marks = array_fill(0, $total_items, '?');
$sql='select uid,ItemName,Price,Quantity from table_items where ItemName IN ('.implode(',', $question_marks). ')';
$stmt = $dbconn->prepare($sql);
$stmt->execute(array_values($ItemNames));

// Fetch 모드를 설정 및 1 row 씩 가져오기
while($row= $stmt->fetch(PDO::FETCH_BOTH)) {
    echo $row[0].' | ';
    echo $row[1].' | ';
    echo $row[2].' | ';
    echo $row[3].'<br />';
}
$dbconn = null;
?>

 

이제 배우는 중이라 그런지 MySQLi 에 비해 불편해보이는 것도 있는거 같다.

익숙해지면 장점이 보일지도.....

 

LIKE 검색어 예제

$likeString = '%' . $string . '%';
 $stmt = $dbconn->prepare("SELECT * FROM tableName WHERE columnName LIKE ?");
 $stmt->bind_param('s', $likeString);
 $stmt->execute();

 

 

Insert 예제

 $stmt = $dbconn->prepare("INSERT INTO db_fruit (id, type, colour) VALUES (:id, :name, :color)");
 $stmt->execute(array('id' => $newId, 'name' => $name, 'color' => $color));

 $stmt = $dbconn->prepare("INSERT INTO db_fruit (id, type, colour) VALUES (? ,? ,?)");
 $stmt->execute(array($newId, $name, $color));

 $stmt = $dbconn->prepare("INSERT INTO db_fruit (`id`, `type`, `colour`) VALUES (:id, :name, :colour)");
 $stmt->bindParam(':id', $newId, PDO::PARAM_INT);
 $stmt->bindParam(':type', $type, PDO::PARAM_INT);
 $stmt->bindParam(':colour', $colour, PDO::PARAM_STR);
 $stmt->execute();

 

https://www.w3schools.com/php/php_mysql_prepared_statements.asp 게시글도 읽어보니 도움 많이 된다.

 

블로그 이미지

Link2Me

,
728x90

안드로이드에서 설정(Setting) 정보를 변경하는 Activity 를 만들어 두어야 할 때 필요할 거 같아서 적어둔다.


준비사항

토글버튼 이미지 2개


toggle_drawable.zip


토글버튼 이미지 2개를 drawable 폴더에 복사하고, toggle_selector.xml 파일을 만든다.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/toggle_on" android:state_checked="true"/>
    <item android:drawable="@drawable/toggle_off" android:state_checked="false"/>

</selector>


activity_setting.xml 은 Layout을 정한다.

여러개의 환경설정 정보가 필요하다면 TableLayout 을 선택하는 것이 좋을 거 같다.

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ToggleButton
        android:id="@+id/btn_toggle1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:background="@drawable/toggle_selector"
        android:checked="true"
        android:text=""
        android:textOff=""
        android:textOn="" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_toggle1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:text=""
        android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>


SettingActivity.java

토글버튼을 선택함에 따라 SharedPreferences 에 값이 변경되도록 하여 관리정보를 알 수 있도록 한다.

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Menu;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;
import android.widget.ToggleButton;

public class SettingActivity extends Activity {

    SharedPreferences pref;
    ToggleButton btn_choice;
    TextView text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_setting);

        btn_choice = (ToggleButton) findViewById(R.id.btn_toggle1);
        text = (TextView) findViewById(R.id.textView1);
        
        pref = getSharedPreferences("pref", Activity.MODE_PRIVATE);
        if(pref.getString("choice", "").equals("1")){
            text.setText("ON");
        } else {
            text.setText("OFF");
        }

        btn_choice.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton arg0, boolean isChecked) {
                if(isChecked == true){
                    text.setText("ON");
                    SharedPreferences.Editor editor = pref.edit();
                    editor.putString("choice", "1");
                    editor.commit();
                } else {
                    text.setText("OFF");
                    System.out.println("토글버튼 해제");
                    SharedPreferences.Editor editor = pref.edit();
                    editor.putString("choice", "0");
                    editor.commit();
                }
            }
        });

    }

}



블로그 이미지

Link2Me

,
728x90

Eclipse 툴에서 패키지명을 변경할 때 해당되는 걸 적어둔다.

번호 1, 2 위에서 마우스 우클릭을 하고 Refactor -> Rename 을 선택하여 변경한다.

번호 3 에서는 패키지명을 직접 변경한다.

번호 4에서는 App 명을 변경하는 걸로 변경한다.




종료하고 다시 읽어들이면 Project Name 이 변경되어 있는 걸 확인할 수 있다.




블로그 이미지

Link2Me

,
728x90

삼성폰에서 Unrecognized profile 2130706433 for video/avc 메시지가 출력된다.

구글링을 해보니까 해결책은 아직 없는것 처럼 나오고 이런 증상을 보이는 폰의 종류들이 나온다.


Samsung Galaxy S6 and Samsung Galaxy S6 Edge+.


Same issue with note 5 upgraded to Android 6.0.1., i have another note 5 with Android 5.1 and is working fine.


Samsung S7 running Android 6.0.1. Screen is black or sometimes flickers dark green on VrVideoView player.


해결책인지는 모르겠는데 적어둔다.

https://developers.google.com/vr/android/reference/com/google/vr/sdk/base/Constants



블로그 이미지

Link2Me

,