태그 보관물: php

PHP로 한글 문자열에서 이(가), 은(는), 을(를) 조사 중에 맞는 것으로 고치기

한글 문자열에 이(가), 은(는), 을(를) 조사가 포함된 경우 맞는 것으로 고쳐서 반환하는 함수를 만들어봤다.

조사 앞글자의 받침 유무에 따라 어떤 조사가 붙을지 선택되는 간단한 로직으로 코드는 짧고 단순하다.

<?php
function fixHangulJosa(string $text): string
{
    return preg_replace_callback('/
        ([가-힣])(
        을\(를\)
        |이\(가\)
        |은\(는\)
        )
    /ux', function ($matches) {
        $coda = (mb_ord($matches[1]) - 0xAC00) % 28;
        $start = $coda ? 0 : 2;
        return $matches[1] . mb_substr($matches[2], $start, 1);
    }, $text);
}

$text = '나뭇잎이(가) 단풍 드는 가을은(는) 우리을(를) 감상에 젖게 만든다.';
// 나뭇잎이 단풍 드는 가을은 우리를 감상에 젖게 만든다.
echo fixHangulJosa($text);

 

이 글은 개발 카테고리에 분류되었고 태그가 있으며 님에 의해 에 작성되었습니다.

PHP에서 pcntl_async_signals(true)와 register_shutdown_function()

PHP에서 pcntl_signal()을 사용하여 시그널을 핸들링 하려면 declare(ticks=1) 선언이 필요하다.
또는 PHP 7.1부터 pcntl_async_signals(true)을 사용하는 것으로 대신할 수 있다.

그런데 SIGINT 시그널이 발생하여 핸들링을 하는 경우 declare(ticks=1)를 쓸 때와 pcntl_async_signals(true)를 쓸 때 각각의 register_shutdown_function()에 등록한 핸들러의 호출 여부가 달라진다. (PHP 7.4에서 테스트)

  • declare(ticks=1)
    • register_shutdown_function()에 등록한 핸들러가 호출되지 않는다.
  • pcntl_async_signals(true)
    • register_shutdown_function()에 등록한 핸들러가 호출된다.

부모 프로세스에서 pcntl_fork()로 나온 자식 프로세스에서 exec()로 또 다른 PHP 스크립트를 실행하는 과정에서 인터럽트에 의한 종료에서도 가능한 정상적인 종료에서와 같은 종료 로직을 거치게 하려고 테스트 하는 과정에서 발견했다.

위 내용이 어렵고 무슨 이야기인지 모른다고 해서 심각하게 들여다 볼 필요는 없다. 단순히 register_shutdown_function()에 등록한 핸들러에 실행 여부를 체크하는 변수 한개만으로 중복 실행만 막으면 된다. 나는 단지 궁금해서 다양한 사례로 테스트를 해본 것이고 그 결과를 기록하는 것 뿐이다. 또한 이 결과는 PHP 버전이 바뀌면 달라질 수도 있다.

정리하면 상황에 따라 register_shutdown_function()에 등록한 핸들러가 중복 실행이 될 수 있으므로 중복 실행이 되지 않도록 방어적인 코딩을 하면 좋을 것 같다.

이 글은 개발 카테고리에 분류되었고 , 태그가 있으며 님에 의해 에 작성되었습니다.

PHP에서 서브도메인간 세션 값이 지워지는 문제

PHP에서 서브도메인간 세션(session)을 공유하기 위한 방법은 어렵지 않다.

만약 my.com, www.my.com, sub.my.com 등 *.my.com 도메인간에 세션을 공유하고 싶다면 PHP 세션 ID가 저장될 쿠키(cookie)의 도메인을 .my.com 으로 하면 된다.

<?php
session_set_cookie_params(0, '/', COOKIE_DOMAIN);
session_start();

그런데 이상하게 A 도메인에 접속해서 만들어진 세션 값이 B 도메인으로 접속하면 세션의 값이 지워지는 문제가 발생했다. 좀 더 정확하게 설명하자면 도메인이 바뀐 상태에서 session_start() 가 호출되면 세션이 빈값으로 초기화가 된다.

우분투 서버에서는 문제가 없다가 CentOS에서 이런 문제가 발생했다. php.ini를 꼼꼼히 살펴봤지만 문제가 될 것 같은 부분은 없었다. 수많은 삽질과 구글링 끝에 문제의 원인을 찾았다.

PHP 확장 모듈중 하나인 수호신(Suhosin)이 원인이었다. 아래의 설정을 추가하면 문제를 해결 할 수 있다.

suhosin.cookie.cryptdocroot=Off
suhosin.session.cryptdocroot=Off