>  기사  >  백엔드 개발  >  마법 메소드 __call()의 영리한 오버로딩

마법 메소드 __call()의 영리한 오버로딩

WBOY
WBOY원래의
2016-08-08 09:31:24827검색

반년 동안 일했는데 대학 4년보다 이번 반년에 더 많은 것을 배운 것 같습니다. 주된 이유는 마음이 차분해지고 목표가 분명해졌기 때문입니다. 하루 종일 게임에 얽매이지 마세요. 대학에 다닐 때 실제로 게임을 하면 정상적인 공부와 일에 영향을 미친다는 것을 깨달았지만, 여전히 밤낮으로 자주 게임을 할 수밖에 없었습니다. 나는 여전히 집에서 게임을 하고 있었는데, 이것이 내가 대학 4년 동안 게임만 하고 왼손과 오른손만 하고 여자친구가 없었던 이유 중 하나이기도 하다. 이제 일을 하다 보니 매일 과제가 생기고, 옆에 재능 있는 분들이 물 만난 오리처럼 프로젝트에 임하는 모습을 보면 따라잡아야겠다는 생각이 들어서 제 자신에게 조금이라도 더 힘을 쏟고 있습니다. 새로운 지식을 배우기 위해 매일매일 일을 하고 있는데, 이제 익숙하지 않았던 Linux를 사용할 수 있게 되었습니다. 현재 업무에 능숙하다는 것(초보, 고급 초보자, 유능함, 능숙함, 전문가)으로 활동, 인터페이스 및 백엔드를 개발했으며 합리적인 수준에서 시스템 프레임워크를 최적화하고 개선했습니다. 제품 운영으로 인해 발생하는 요구 사항을 신속하게 지원할 수 있습니다. 물론 한 가지 느낀 점은 프로그래머는 정말 이상한 집단이다. 대부분 항상 자신의 아이디어가 최고라고 생각한다. 물론 이는 자신감이라고 생각하지만 토론 중 공격적인 태도가 반드시 좋은 것은 아니기 때문에 다른 사람의 의견을 경청해야 자신의 단점을 발견할 수 있을 뿐만 아니라, 또한 좋은 우정을 쌓으세요: " ". 지난 6개월 동안 제 심정을 너무 많이 말씀드렸는데, 끝까지 함께 읽어주셔서 감사합니다^_^.

이제 실제 질문에 들어가서 PHP의 마법의 방법을 능숙하게 사용하는 방법에 대해 이야기해 보겠습니다. 저는 이것이 대부분의 프로젝트에서 사용될 것이라고 믿습니다.

먼저 설명하겠습니다. 저는 이미 제 프로젝트에서 이 작은 트릭을 아주 잘 사용했고, 이것이 우리 프로젝트에 큰 편의를 가져다주었습니다. 여기에서 몇 가지 세부 사항을 설명하겠습니다. 계속해서 읽어 보시기 바랍니다.

프로젝트에는 게임의 로봇 오픈 기간, 결제 수단 활성화 여부, 쇼핑몰 내 타이틀 표시 구성 등 구성할 수 있는 많은 양의 구성 정보가 있어야 합니다. 이러한 구성 정보의 특징 중 하나는 특정 규칙이 없으며 실제 상황에 따라 제품 작동이 언제든지 변경될 수 있다는 것입니다. .. 생각해보면 아마도 하나뿐인 정보가 테이블에 저장되어 있기 때문에 이 정보에 대한 규칙은 없지만 다른 방법을 생각해야 한다는 특징이 있습니다. 과하지 않을 것이고 일반적으로 배열은 구성해야 하는 모든 정보를 저장할 수 있으므로 JSON 문자열 저장소 정보를 사용하는 것이 좋은 선택입니다. 필요할 때 json_decode를 꺼내서 바로 사용할 수 있습니다. 이를 달성하기 위해 PHP의 마법 메소드를 교묘하게 사용하는 방법을 살펴보겠습니다.

여기서 먼저 PHP의 마법 메소드인 __call()을 이해해야 합니다. 이 기능을 다음과 같이 설명하는 공식 PHP 문서를 확인하세요.

<span>public</span> <span>mixed</span> __call ( <span>string</span> <span>$name</span> , <span>array</span> <span>$arguments</span><span> )

__call() is triggered when invoking inaccessible methods in an </span><span>object</span> context.

객체에서 접근할 수 없는 메소드(권한 없음, 존재하지 않음)가 호출될 때 이 함수가 실행된다는 의미입니다. 함수의 $name 매개변수는 호출된 함수의 이름이고, $arguments는 매개변수입니다. 호출된 함수의 배열입니다. 다음 예를 살펴보세요.

<span>class</span><span> Test
{
    </span><span>public</span> <span>function</span> __call(<span>$name</span>, <span>$arguments</span><span>)
    {
        </span><span>echo</span> "你调用了一个不存在的方法:\r"<span>;
        </span><span>echo</span> "函数名:{<span>$name</span>}\r"<span>;
        </span><span>echo</span> "参数: \r"<span>;
        </span><span>print_r</span>(<span>$arguments</span><span>);
    }
}

</span><span>$T</span> = <span>new</span><span> Test();
</span><span>$T</span>->setrobottime("12", "18");

이 함수는 다음과 같은 결과를 출력합니다

<span>你调用了一个不存在的方法:
函数名:setrobottime
参数: 
Array
(
    [</span>0] => 12<span>
    [</span>1] => 18<span>
)</span>

이런 식으로 함수를 직접 정의할 수는 없지만 이 기능을 사용하여 뭔가를 할 수 있습니다. 코드의 구현 아이디어를 살펴보겠습니다. 주요 아이디어는 데이터베이스 연결과 같은 가정입니다.

<span>class</span><span> Config
{
    </span><span>/*</span><span>*
     * 这里假定下数据库表名为
     * config.config,
     * 字段为:
     * config_key varchar(50),
     * config_value text,
     * primary key(config_key)
     *
     * 数据库连接为$link
     * 插入方法封装为query
     * 获取一条信息方法封装为getOne
     </span><span>*/</span>
    <span>/*</span><span>*
     * 要进行的操作
     </span><span>*/</span>
    <span>private</span> <span>static</span> <span>$keys</span> = <span>array</span><span>(
        </span><span>//</span><span>'调用方法' => 'key',</span>
        'roboottime'    => 'ROBOOTTIME',
        'dailysignin'   => 'DAILYSIGNIN',<span>
    );

    </span><span>/*</span><span>*
     * 设置方法
     * @param string $config_key 配置项key
     * @param string $config_value 配置型内容(一般为json格式)
     * @returne boolen true/false 插入是否成功
     </span><span>*/</span>
    <span>private</span> <span>function</span> set(<span>$config_key</span>, <span>$config_value</span><span>){
        </span><span>$sql</span> = "insert into config.config (config_key,config_value) values ('{<span>$config_key</span>}','{<span>$config_value</span>}') on duplicate key update config_value='{<span>$config_value</span>}'"<span>;
        </span><span>return</span> <span>$link</span>->query(<span>$sql</span><span>);
    }

    </span><span>/*</span><span>*
     * 获取值的方法
     * @param $config_key 要获取的配置的key
     * @returne string/false json字符串/失败
     </span><span>*/</span>
    <span>private</span> <span>function</span> get(<span>$config_key</span><span>)
    {
        </span><span>$sql</span> = "select * from config.config where config_key='{<span>$config_key</span>}'"<span>;
        </span><span>if</span>(<span>$ret</span> = <span>$link</span>->getOne(<span>$sql</span>,<span> MYSQL_ASSOC)){
            </span><span>return</span> <span>$ret</span><span>;
        }
        </span><span>return</span> <span>false</span><span>;
    }

    </span><span>/*</span><span>*
     * 重载魔术方法
     * @param string $name 被调用的方法名
     * @param array $arguments 调用时传递的参数
     * @return mixed 返回结果
     </span><span>*/</span>
    <span>public</span> <span>function</span> __call(<span>$name</span>, <span>$arguments</span><span>)
    {
        </span><span>$act</span>    = <span>substr</span>(<span>$name</span>, 0, 3<span>);
        </span><span>$func</span>   = <span>substr</span>(<span>$name</span>, 3<span>);
        </span><span>if</span>(!<span>in_array</span>(<span>$func</span>, self::<span>$keys</span><span>)){
            </span><span>return</span> <span>false</span><span>;
        }
        </span><span>if</span>(<span>$act</span> == 'set'<span>)
        {
            </span><span>return</span> <span>$this</span>->set(self::[<span>$func</span>], <span>$arguments</span>[0<span>]);
        }
        </span><span>elseif</span>(<span>$act</span> == 'get'<span>)
        {
            </span><span>return</span> <span>$this</span>->get(self::[<span>$func</span><span>]);
        }
        </span><span>return</span> <span>false</span><span>;
    }
}</span>

이렇게 하면 하나의 테이블에 여러 정보를 저장할 수 있고 호출 시에도 매우 편리합니다. Config::$keys 배열에 정보를 확장하기만 하면 됩니다. 가능 이 테이블에 어떤 구성이 저장되어 있는지 명확하게 알 수 있습니다.

사용시 이렇게 보관 및 회수가 가능합니다

<span>$config</span> = <span>new</span><span> Config();

</span><span>$info</span> = <span>array</span>("12","20"<span>);

</span><span>//</span><span>设置</span>
<span>$config</span>->setroboottime(json_encode(<span>$info</span><span>));

</span><span>//</span><span>获取</span>
<span>$config</span>->getroboottime();

다음은 주의할 점입니다. 이러한 구성 정보는 일반적으로 Redis가 중단된 후 데이터베이스에서 복구되는 것을 방지하기 위해 데이터베이스에 저장됩니다. db와의 상호작용을 줄이기 위해 캐시에 직접 배치됩니다.

이 글의 저작권은 저자(luluyrt@163.com)에게 있습니다. 글을 재인쇄한 후, 저자와 원문 링크를 반드시 밝혀야 합니다. 기사 페이지의 명확한 위치에 제공되지 않으면 당사는 법적 책임 권리를 추구할 권리를 보유합니다.

posted @ 2015-01-10 12:23 런닝맨 읽기(...) 댓글(...) 모음 편집

댓글 새로고침 페이지 새로고침 맨 위로 돌아가기

블로그파크 홈페이지 보웬뉴스 플래시 프로그래머 채용 지식베이스

公告

Copyright ©2015 奔跑的Man

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.