Programing

PHP 클래스에 코드를 포함 할 수 있습니까?

lottogame 2021. 1. 5. 07:41
반응형

PHP 클래스에 코드를 포함 할 수 있습니까?


PHP 클래스를 만들고 싶습니다. Myclass.php라고합시다. 이제 그 클래스 내에서 클래스 자체와 일부 인스턴스 변수를 정의하고 싶습니다. 그러나 모든 메소드는 Myclass_methods.php 파일에서 가져와야합니다. 그 파일을 클래스 본문에 포함시킬 수 있습니까?

나는 이것을 분리하고 싶은 이유가 있습니다. 요컨대, 클래스의 비즈니스 로직을 변경할 수있는 백엔드를 갖게 될 것이며 다른 모든 것은 그대로 유지해야합니다. 시스템은 나를 위해 모든 ORM 및 기타 항목을 유지합니다.

그러나 이것이 나쁜 생각이라면 비즈니스 로직 (이 경우 사용자 정의 메서드)을 편집 한 후 전체 클래스 파일을 다시 생성하는 것이 좋습니다.

성능 질문 : 한 번의 요청 중에 Myclass.php가 한 번만 포함되는 경우 실제로 Myclass_methods.php도 한 번만 포함되어야합니다. 틀릴 수도 있습니다. 전문가?


아니요. 클래스 본문에 파일을 포함 할 수 없습니다.
클래스를 정의하는 파일에서 메서드 본문 또는 클래스 본문 외부에 파일 만 포함 할 수 있습니다 .

귀하의 설명에서 나는 이것을 원합니다.

<?php // MyClass.php
class MyClass
{
    protected $_prop;
    include 'myclass-methods.php';
}

<?php // myclass-methods.php
public function myMethod()
{
   $this->$_prop = 1;
}

이 코드를 실행하면

Parse error: syntax error, unexpected T_INCLUDE, expecting T_FUNCTION

이것이 가능한 것은 무엇입니까?

<?php // MyClass.php
class MyClass
{
    protected $_prop;
    public function __construct() // or any other method
    {
        include 'some-functions.php';
        foo($b); // echoes 'a';
    }
}

<?php // some-functions.php
$b = 'a';
function foo($str)
{
   echo $str;
}

이렇게하면 포함 파일의 내용을 클래스 범위가 아닌 메서드 범위로 가져옵니다. include 파일에 함수와 변수를 포함 할 수 있지만 메서드는 포함 할 수 없습니다. 전체 스크립트를 여기에 넣을 는 있지만 방법이 수행하는 작업을 변경 해서는 안됩니다.

<?php // MyClass.php
    // ...
    public function __construct($someCondition)
    {
        // No No Code here
        include ($someCondition === 'whatever') ? 'whatever.php' : 'default.php';
    }
    // ...

<?php // whatever.php
    echo 'whatever';

<?php // default.php
    echo 'foo';

그러나 이러한 방식으로 클래스를 패치하여 다른 동작을 표시하는 것은 OOP에서 수행하는 방식이 아닙니다. 그것은 명백한 잘못이며 눈이 피를 흘릴 것입니다.

동작을 동적으로 변경하고 싶기 때문에 클래스를 확장하는 것도 좋은 옵션이 아닙니다 (아래 이유 참조). 정말로하고 싶은 것은 인터페이스를 작성하고 클래스가이 인터페이스를 구현하는 객체를 사용하도록 만드는 것입니다. 따라서 적절한 메서드를 사용할 수 있는지 확인합니다. 이를 전략 패턴 이라고하며 다음 과 같이 작동합니다.

<?php // Meowing.php 
interface Meowing
{
    public function meow();
}

이제 모든 야옹 행동이 준수해야하는 계약, 즉 야옹 방법이 있습니다. 다음으로 야옹 행동을 정의합니다.

<?php // RegularMeow.php
class RegularMeow implements Meowing
{
    public function meow()
    {
        return 'meow';
    }
}

이제 사용하려면 다음을 사용하십시오.

<?php // Cat.php
class Cat
{
    protected $_meowing;

    public function setMeowing(Meowing $meowing)
    {
        $this->_meowing = $meowing;
    }

    public function meow()
    {
        $this->_meowing->meow()
    }
}

Meowing TypeHint 를 setMeowing에 추가하여 전달 된 매개 변수가 Meowing 인터페이스를 구현하는지 확인합니다. 또 다른 야옹 행동을 정의 해 보겠습니다.

<?php // LolkatMeow.php
class LolkatMeow implements Meowing
{
    public function meow()
    {
        return 'lolz xD';
    }
}

이제 다음과 같은 동작을 쉽게 교환 할 수 있습니다.

<?php
require_once 'Meowing.php';
require_once 'RegularMeow.php';
require_once 'LolkatMeow.php';
require_once 'Cat.php';

$cat = new Cat;
$cat->setMeowing(new RegularMeow);
echo $cat->meow; // outputs 'meow';
// now to change the behavior
$cat->setMeowing(new LolkatMeow);
echo $cat->meow; // outputs 'lolz xD';

추상 BaseCat 및 meow 메서드 를 정의한 다음 그로부터 구체적인 RegularCat 및 Lolkat 클래스를 파생 하여 상속통해 위의 문제를 해결할 수도 있지만 달성하려는 것을 고려해야합니다. 고양이가 야옹하는 방식을 변경하지 않을 경우 상속을 사용하지만 RegularCat과 Lolkat이 임의의 야옹을 수행 할 수 있어야한다면 전략 패턴을 사용하십시오.

PHP의 더 많은 디자인 패턴 은 다음 리소스를 확인하세요.


관련 기본 기능을 사용하여 코어 클래스를 만든 다음 필요한 메서드로이를 확장하는 것이 생각이 아닐 수도 있습니다. 더 논리적 인 접근 방식처럼 보입니다.


이 문제가 메서드가 포함 된 기본 클래스, 데이터가 포함 된 하위 클래스 및 동적 클래스로드를 사용하여이 문제가 가장 잘 해결되지 않는 이유가 너무 명확하지 않다는 것부터 시작하겠습니다. 타당한 이유가 있다고 생각합니다.

공급자가 PHP 5.4를 지원하면 트레이 트를 사용하여 원하는 작업을 수행 할 수 있습니다.

코드 파일 :

if ($pet === 'dog') include 'dog.php';
elseif ($pet === 'cat') include 'cat.php';
else die('Unknown pet');

class Pet {
  use PetSounds;
}

$myPet = new Pet();
$myPet->speak();

cat.php 파일

trait PetSounds {
  function speak() { echo 'meow'; }
}

dog.php 파일

trait PetSounds {
  function speak() { echo 'woof'; }
}

두 포함 파일의 이름을 동일하게 지정하고 다른 하위 디렉터리에 넣은 다음 set_include_path ()를 사용하거나 __autoload () 함수를 정의하여 둘 중에서 선택하면이를 더욱 깔끔하게 만들 수 있습니다. 그래도 말했듯이이 동일한 문제는 상속을 사용하여 더 잘 해결할 수 있습니다. 하지만 다중 상속 유형 문제가있는 경우, 예를 들어 3 가지 머리 유형에 5 가지 색상의 4 가지 종류의 애완 동물이 있고 60 가지 클래스 각각에 대해 다른 조합의 방법이 필요한 경우 이것이 올바른 해결책입니다. .

5.4는 현재 출시 후보 일뿐 (2012 년 2 월 24 일 기준)이며 한 번 출시 된 후에도 대부분의 호스트는 여러 달 동안이를 지원하지 않을 것입니다. 5.3이 출시 된 후 18 개월이 지나야 지원할 수 있습니다. 그때까지는 완전히 별개의 완전한 클래스 파일을 작성해야합니다. 그러나 궁극적 인 특성 변경을 염두에두고 클래스 형식을 지정할 수 있습니다.

지금 당장은 마법 방법을 사용하여 원하는 것을 부분적으로 얻을 수 있으며 사용 가능할 때 특성으로 쉽게 업그레이드 할 수 있습니다.

코드 파일 :

if ($pet === 'dog') include 'dog.php';
elseif ($pet === 'cat') include 'cat.php';
else die('Unknown pet');

class Pet {
  public function __call($name, array $arguments)
  {
    array_unshift($arguments, $this);
    return call_user_func_array("TraitFunc_$name", $arguments);
  }
}

$myPet = new Pet();
$myPet->speak();

cat.php 파일

function TraitFunc_speak(Pet $that) { echo 'meow'; }

dog.php 파일

function TraitFunc_speak(Pet $that) { echo 'woof'; }

그러나 함수가 개인 및 보호 클래스 속성 및 메서드에 액세스 할 수 없으며이 메서드를 사용하여 __get ()과 같은 매직 메서드를 제공 할 수 없다는 점에서 제한됩니다. 특성은 이러한 한계를 모두 해결할 것입니다.


이를 위해 특성을 사용하는 것은 어떻습니까? 이것이 허용 가능한 옵션입니까? 이것은 내가 현재 실험하고있는 것이고 꽤 오랫동안 작동하는 것 같습니다.

내가하는 일의 단순화 된 버전은 기본적으로 이와 같습니다. 공유 코어 파일과 여러 프로젝트가있는 응용 프로그램이 있습니다. 그 프로젝트에는 모듈이 있습니다. 핵심 수준에서 전체 프로젝트에 사용할 수있는 기능을 원하지만 해당 특정 프로젝트에만 사용할 수 있습니다.

내 프로젝트 컨트롤러

if(is_file(PROJECT_PATH.'/project_extensions.trait.php')){
  // additional functions for this specific project
  require_once(PROJECT_PATH.'/project_extensions.trait.php');
}else{
  // no additional functions
  trait Extensions{};
}


Class Project{
  USE Extensions;

  // default functions shared between all projects
  function shared_stuff(){

  }
}

확장 파일

trait Extensions{
  // project-specific extensions
  function this_project_only(){
    echo 'Project Only';
  }
}

프로젝트의 모듈 파일

class MyModule extends Modules{ // modules extends projects in a different class not relevant here

  function do_something(){
    echo $this->project_only();
  }
}

PHP5.4 릴리스 부터 다음 과 같은 동적 개체를 만들 수 있습니다 . https://github.com/ptrofimov/jslikeobject

그러나 이것이 최선의 방법 아닙니다 .


Reviving an old question but this is a fairly simple solution. Do you need the common function calls to be exclusive to your class? If not, simply include your common function file(s) within the same scope as your class. You will need to create methods in your class but they will only need to call the common function. Here's a simple SOAP server example:

<?php

include 'post_function.php';

$server = new SoapServer( null, array('uri' => "http://localhost/") );
$server->setClass(  'postsoapclass' );
$server->handle();


class postsoapclass
{
    public function animalNoise( $animal )
    {
        return get_animal_noise($animal);
    }
}

?>

post_function.php

<?php

function get_animal_noise($animal)
{
    if(strtolower(trim($animal)) == 'pig')
    {
        return 'Oink';
    }
    else 
    {
        return 'This animal is mute';
    }
}

?>

I have had to do what you are describing in cases where I maintain a free version and a premium version of the same software. Because, as @Gordon noted, you cannot do exactly this:

class SomeClass {  

  premium_file = "premium.php";
  if (file_exists($premium_file)) {
    require($premium_file);
  }

Instead I do this:

  premium_file = "premium.php";
  if (file_exists($premium_file)) {
    require($premium_file);
  }

  class SomeClass {
    ...

For functions you want to reference, create class methods in the main class, and call the included file's method, passing the $this pointer as a parameter. So that I can tell at a glance where functions are, I will prefix the name of the included functions as shown below:

  class SomeClass {
    ... 
    // Premium functions
    public function showlist() {
      premium_showlist($this);
    }

I came across this recently, and came up with a solution, that helped in my case. I wanted many functions in a class, but the class became bloated, so wanted to separate out the class functions into groups for readability. It took a little time to accomplish, but since the functions of the class didn't rely (much) on $this, I removed "$this" from the class functions and created several helper files to include those functions. When $this was necessary, I could nevertheless move the function into a helper file, by passing $this to the function, adding public set/get functions where necessary. It's a hack, but it's sure to help someone

` class myClass { var x;

    function myClass()
    {
        $this->x = 0;
    }

    function myFunc1Group1()
    {
        $x = $this->x;
        $x++;
        $this->x = $x;
    }
    function myFunc2Group1(){}

    function myFunc1Group2(){}
    function myFunc2Group2(){}
}

`

can be worked around to

` class myClass { var x;

    function myClass()
    {
        $this->x = 0;
    }

    function doSomething()
    {
        // not called on $this but takes $this as a parameter
        myFunc1Group1($this);
    }
}

`

and helper function set 1

function myFunc1Group1($THIS_OBJECT) { $x = $THIS_OBJECT->getX(); $x++; $THIS_OBJECT->setX($x); } function myFunc2Group1($THIS_OBJECT){}

and helper function set 2, etc.

Probably not the best route in all cases, but helped me out a lot. Basically the class functions were only to construct and delegate, and the calculations were put into helpers.

ReferenceURL : https://stackoverflow.com/questions/1957732/can-i-include-code-into-a-php-class

반응형