>  기사  >  백엔드 개발  >  PHP에서 Runkit 확장을 사용하는 방법

PHP에서 Runkit 확장을 사용하는 방법

醉折花枝作酒筹
醉折花枝作酒筹앞으로
2021-06-02 18:05:041330검색

이 글에서는 PHP에서 Runkit 확장 기능을 사용하는 방법을 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.

PHP에서 Runkit 확장을 사용하는 방법

이번에는 재미있는 확장 프로그램을 가져왔습니다. 우리는 PHP가 실행 중일 때, 즉 배포가 완료된 후에는 상수 값을 수정할 수 없으며 메서드 본문 내부의 구현을 수정할 수도 없다는 것을 알고 있습니다. 즉, 코딩을 마친 후 코드를 서버에 업로드하게 되는데, 이때 코드를 수정하지 않고는 상수값을 수정할 수 없습니다. 상수 자체는 수정할 수 없습니다. 그러나 Runkit 확장은 이 기능을 수행하는 데 도움이 될 수 있습니다.

상수의 동적 수정

define('A', 'TestA');

runkit_constant_redefine('A', 'NewTestA');

echo A; // NewTestA

멋지지 않나요? 이 런킷 확장은 런타임 시 일부 상수, 메서드 본문 및 클래스를 동적으로 수정할 수 있게 해주는 기능적 확장입니다. 물론 시스템 보안 관점에서 볼 때 이 확장은 그다지 권장되지 않습니다. 상수의 의미는 변하지 않는 수량이므로 수정해서는 안 됩니다. 마찬가지로, 런타임 시 함수 본문이나 클래스 정의의 내용을 동적으로 변경하면 이러한 함수나 클래스를 호출하는 다른 코드에 영향을 미칠 수 있습니다. 따라서 이 확장은 위험한 확장입니다.

동적으로 상수를 수정하는 것 외에도 runkit_constant_add() 및 runkit_constant_remove() 함수를 사용하여 상수를 동적으로 추가하거나 삭제할 수도 있습니다.

설치

런킷 확장을 설치하려면 github에서 다운로드한 다음 확장을 정상적으로 컴파일해야 합니다. pecl 다운로드가 오래되었습니다.

PHP5: http://github.com/zenovich/runkit

PHP7: https://github.com/runkit7/runkit7.git

Clone 성공 후 일반 확장 컴파일 및 설치 단계를 따르세요.

phpize
./configure
make
make install

서로 다른 PHP 버전은 서로 다른 확장 버전을 설치해야 합니다. 동시에 runkit7은 아직 개발 중이며 다음과 같은 일부 기능은 아직 지원되지 않습니다. runkit_import

  • runkit_lint_file

  • runkit_lint

  • runkit_sandbox_output_handler

  • runkit_return_value_used

  • Runkit_ Sandbox

  • R unkit_Sandbox_Parent

  • 본 글의 테스트 코드를 작성할 때 위의 함수나 클래스는 지원되지 않습니다. PHP5 환경을 사용하여 원래 확장 기능을 정상적으로 사용할 수 있는지 테스트할 수 있습니다.

  • 수퍼 전역 변수 키 보기

    print_r(runkit_superglobals());
    //Array
    //(
    //    [0] => GLOBALS
    //    [1] => _GET
    //    [2] => _POST
    //    [3] => _COOKIE
    //    [4] => _SERVER
    //    [5] => _ENV
    //    [6] => _REQUEST
    //    [7] => _FILES
    //    [8] => _SESSION
    //)
  • 이 기능은 실제로 현재 실행 중인 환경에서 모든 슈퍼 전역 변수 키 이름을 확인합니다. 이것들은 우리가 일반적으로 사용하는 슈퍼글로벌 변수 중 일부이므로 하나씩 설명하지는 않겠습니다.
  • 메소드 관련 연산

메소드 연산은 상수 연산과 동일하며, 다양한 메소드를 동적으로 추가, 수정, 삭제, 이름 변경할 수 있습니다. 먼저, 동적 런타임 중 메소드 본문의 로직 코드를 수정할 때 가장 신경쓰는 부분을 살펴보겠습니다.

function testme() {
  echo "Original Testme Implementation\n";
}
testme(); // Original Testme Implementation
runkit_function_redefine('testme','','echo "New Testme Implementation\n";');
testme(); // New Testme Implementation

는 testme() 메서드를 정의한 다음 runkit_function_redefine()을 통해 구현을 수정합니다. 마지막으로 testme()가 다시 호출되면 새로 수정된 구현이 출력됩니다. 그렇다면 PHP에 포함된 메서드를 수정할 수 있나요?
// php.ini runkit.internal_override=1
runkit_function_redefine('str_replace', '', 'echo "str_replace changed!\n";');
str_replace(); // str_replace changed!

runkit_function_rename ('implode', 'joinArr' );
var_dump(joinArr(",", ['a', 'b', 'c'])); 
// string(5) "a,b,c"


array_map(function($v){
   echo $v,PHP_EOL;
},[1,2,3]);
// 1
// 2
// 3
runkit_function_remove ('array_map');

// array_map(function($v){
//   echo $v;
// },[1,2,3]);
// PHP Fatal error:  Uncaught Error: Call to undefined function array_map()
코드의 주석을 보면 PHP와 함께 제공되는 메서드와 함수를 동적으로 수정하려면 php.ini에서 runkit.internal_override=1만 설정하면 됩니다. 예를 들어 첫 번째 문단에서는 텍스트 문단을 직접 출력할 수 있도록 str_replace() 메서드를 수정했습니다. 그런 다음 implode()와 마찬가지로 이 JoinArr()을 사용할 수 있도록 implode()의 이름을 JoinArr()로 바꿉니다. 마지막으로 array_map() 메서드를 제거했습니다. 이 메서드를 다시 호출하면 오류가 보고됩니다.

클래스 메소드 관련 연산

클래스 내부 메소드 함수의 연산은 위의 가변 메소드 연산과 유사하지만 PHP에 포함된 클래스를 수정할 수 없습니다. 직접 시도해 볼 수 있습니다.

//runkit_method_add('PDO', 'testAddPdo', '', 'echo "This is PDO new Func!\n";');
//PDO::testAddPdo();
// PHP Warning:  runkit_method_add(): class PDO is not a user-defined class

오류 메시지에서 알 수 있듯이 PDO 클래스는 사용자 정의 클래스가 아니므로 관련 작업에 runkit 함수를 사용할 수 없습니다. 그런 다음 사용자 정의 클래스가 Runkit을 사용하여 동적 작업을 수행하는 방법을 살펴보겠습니다.

class Example{
}

runkit_method_add('Example', 'func1', '', 'echo "This is Func1!\n";');
runkit_method_add('Example', 'func2', function(){
    echo "This is Func2!\n";
});
$e = new Example;
$e->func1(); // This is Func1!
$e->func2(); // This is Func2!

runkit_method_redefine('Example', 'func1', function(){
    echo "New Func1!\n";
});
$e->func1(); // New Func1!

runkit_method_rename('Example', 'func2', 'func22');
$e->func22(); // This is Func2!

runkit_method_remove('Example', 'func1');
//$e->func1();
// PHP Fatal error:  Uncaught Error: Call to undefined method Example::func1()

빈 클래스를 정의한 다음 여기에 두 개의 메서드를 동적으로 추가한 다음 메서드 1을 수정하고 메서드 2의 이름을 바꾸고 마지막으로 메서드 1을 삭제했습니다. 일련의 작업은 실제로 위의 일반 메서드와 동일합니다.

요약

위에서 언급했듯이 이 확장은 상대적으로 위험한 확장입니다. 특히 runkit.internal_override가 켜져 있는 경우 PHP의 기본 기능을 수정할 수도 있습니다. 하지만 꼭 사용해야 한다면 그 기능은 매우 유용합니다. 방문자 패턴과 마찬가지로 "대부분의 경우 방문자 패턴이 필요하지 않지만 방문자 패턴이 필요할 때는 실제로 필요합니다." 이 런킷 확장 세트에도 마찬가지입니다.

推荐学习:php视频教程

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202006/source/%E4%B8%80%E8%B5%B7%E5%AD%A6%E4%B9%A0PHP%E7%9A%84runkit%E6%89%A9%E5%B1%95%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8.php

위 내용은 PHP에서 Runkit 확장을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제