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:
- 0 : PHP 시스템 로거
- 1 : 이메일
- 3 : 파일
- 4 : SAPI 로깅 핸들러에 직접 로깅
Array
<?php
// 문자열이 배열 안에 있는지 여부
in_array("test", $arr)
// POST 방식으로 넘어온 별수를 p_ 접두어를 붙여 쓸 수 있다.
extract($_POST,EXTR_PREFIX_ALL,"p");
Foreach
<?php
foreach($arr as $row) {
echo $row;
}
Cookie
<?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
<?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
파라미터 받는 방법
<?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