PHP로 개발하면서 작성한 노트

Mar 22, 2017

PHP로 개발하면서 작성한 노트이다.

기본

Type

<?php
// 타입 확인
gettype($foo); // string

// 함수 존재 여부
function_exists("fopen"); // 1

error_log

<?php
// 파일로 로그 남기기
error_log("Error message.", 3, "/path/file");

message_type:

Array

<?php
// 문자열이 배열 안에 있는지 여부
in_array("test", $arr)

// POST 방식으로 넘어온 별수를 p_ 접두어를 붙여 쓸 수 있다.
extract($_POST,EXTR_PREFIX_ALL,"p");

Foreach

<?php
foreach($arr as $row) {
    echo $row;
}
<?php
// 생성
setcookie("user", "Kichul", time() + 3600);

// 사용
echo $_COOKIE["user"]; // Kichul

// 제거
setcookie("user", "", time() - 3600);

환경변수 $_SERVER

<?php
$_SERVER['HTTP_USER_AGENT']; // Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)

자주 사용하는 함수

array_unique

배열에서 중복된 값을 제거

<?php
array_unique(array("a", "a", "b")); // "a", "b"

extract

배열의 키와 같은 이름의 변수로 만들어주는 함수.

<?php
$foo = array(
    "bar" => "1",
    "xar" => "2"
);
extract($db_config);

echo $bar; // 1
echo $xar; // 2

preg_quote

정규식 문자를 escape 한다.

<?php
$pattern_string = "??This string?? will be encoded.";
echo sprintf("/%s/", preg_quote($pattern_string)); // /\?\?This string\?\? will be encoded\./

파일

<?php
// 파일 읽기
$handle = fopen("/home/php_script/test.text", "r");
if($handle) {
    while (!feof($handle)) {
        echo fgets($handle);
    }

    fclose($handle);
}

// 현재 커맨드를 실행하는  디렉터리
getcwd();

시간

microtime float 형으로 변경하기

<?php
array_sum(explode(' ',microtime())) // 1490150613.7596

포맷에 맞게 datetime 출력

<?php
// 2017-04-12 11:13:54
date("Y-m-d H:i:s", time());

디자인 패턴

싱글톤 패턴

설정이나 Logger, DB를 다루는 클래스를 만들 때 자주 사용한다.

<?php
class SingletonClass
{
    protected static $instance; // 현재 클래스의 인스턴스
    private $config; // 멤버 변수

    // 멤버 변수를 가져오는 메소드
    public function get()
    {
        if ($this->config) {
            return $this->config;
        } else {
            $initial_config = array(
                "foo" => "1",
                "bar" => "2"
            );
            $this->config = $initial_config;

            return $initial_config;
        }
    }

    // 싱글톤 인스턴스를 가져오는 메소드
    final public static function getInstance()
    {
        if (!isset(static::$instance)) {
            static::$instance = new static();
        }

        return static::$instance;
    }
}

사용 방법:

<?php
$Config = Config::getInstance()->get();
echo $Config["foo"]; // 1
echo $Config["bar"]; // 2

PDO

PDO 매뉴얼

<?php
# 접속
$pdo = new PDO(
    'mysql:host=localhost;dbname=mydb',
    'user',
    'passwd'
);

# 조회
$sth = $pdo->prepare("select * from images");
$sth->execute();
$result = $sth->fetch(PDO::FETCH_ASSOC);

Monolog (로그 라이브러리)

로그를 남기기 위해 기본적으로 Monolog를 다음과 같이 사용할 수 있다.

<?php
// Alias 지정
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

// Handler 생성 (표준 출력)
$handler = new StreamHandler('php://stdout');

// Logger 생성
$logger = new Logger('ApplicationLog');

// Logger에 Handler 넣기
$logger->pushHandler($handler);

// 로그 기록하기
$logger->info(LOG_TEXT)

이번에는 Monolog로 전역에서 사용할 수 있는 Logger를 만들겠다. 매뉴얼에 따르면 Registry라는 싱글톤을 사용해서 어디에서든 호출할 수 있다.

<?php
// Alias 지정
use Monolog\Registry;

// ... logger 선언은 위 내용과 같음 ...

// Logger를 전역에서 사용할 수 있도록 추가
Registry::addLogger($logger);

// 어디서든 다음과 같이 사용할 수 있다.
Registry::getInstance("ApplicationLog")->info(LOG_TEXT);

지금까지 StreamHandler로 예제를 만들었는데, 다음과 같은 핸들러를 사용할 수 있다.

<?php
// 표준 입출력, 파일로 보내는 Handler
use Monolog\Handler\StreamHandler;

// 아무런 출력도 생기지 않음.
use Monolog\Handler\NullHandler;

// 시스템 로그 파일에 기록 (centos : /var/log/message)
use Monolog\Handler\SyslogHandler;

// PHP 에러로그 파일에 기록
use Monolog\Handler\ErrorLogHandler;

Formatter를 설정하지 않으면 기본적인 포맷으로 로그가 기록된다. 이것을 원하는 형식으로 지정하려면 Handler에 Formatter를 설정해야 한다.

<?php
// Alias 지정
use Monolog\Formatter\LineFormatter;

// 새로운 형식으로 formatter 생성
$formatter = new LineFormatter("%message%\n");

// handler에서 formatter를 지정할 수 있다.
$handler->setFormatter($formatter);

PHP 에러 로그 확인하기

아파치는 다음과 같은 형태로 로그 파일이 생성된다.

/var/log/httpd/호스트명-access_log
/var/log/httpd/호스트명-error_log

셸에서 실행할 때는 ini 파일에서 로그 파일의 위치를 알아낼 수 있다.

# 어떤 php.ini 파일을 불러오는지 확인
php --ini
Loaded Configuration File:         /etc/php.ini

# error_log 설정 확인
cat /etc/php.ini | grep error_log
error_log = /home/test/php_errors.log

CLI

파라미터 받는 방법

$argv 매뉴얼 페이지

<?php
print_r($argv);

php.ini 설정

exec 함수에 사용할 커맨드 제한하기

특정 디렉터리에 있는 커맨드만 실행할 수 있게 제한할 수 있다.

; 안전모드 실행여부
safe_mode = On

; exec 함수에서 허용할 디렉터리를 설정
safe_mode_exec_dir = "/path/bin"

특정 함수 호출 제한

보안에 위협이 될만한 함수를 제한할 수 있다.

; 특정 함수 사용 제한하기
disable_functions = "passthru,proc_open,pcntl_exec,shell_exec,system,eval,popen"

기타 이슈

phar로 빌드할 때 에러 발생

phar 파일을 만들 때, 파일을 압축하는 부분에서 다음 에러가 발생했다.

unable to create temporary file

open file descriptor의 수를 확인하고, 너무 작으면 올려준다.

# 확인
ulimit -n
1024

# 변경
ulimit -n 20000

위 커맨드는 일시적으로 적용하는 것이라서 설정을 유지하려면 다음과 같이 설정 파일을 이용하거나 profile 파일에 추가해야 한다.

# 프로세스 사용자에 대한 설정
vi /etc/security/limits.conf

# profile에 설정. 가장 아래에 ulimit -n 20000 추가
vi /etc/profile

# 적용
source /etc/profile