PHP 객체 참조 및 객체 최적화 전략

高洛峰
풀어 주다: 2016-10-17 11:12:10
원래의
1150명이 탐색했습니다.

PHP5에서 객체지향적 사고가 등장하면서 PHP 프로그램을 구성할 때 프로그램에 대한 새로운 요약이 생겼고, 객체의 특성을 클래스로 캡슐화하는 것, 특히 PHP 프레임워크를 실제 프로젝트에 적용할 때, 클래스 객체를 구성하는 것, 그리고 많은 것들이 있습니다. 클래스 객체 호출에 중점을 둡니다.

우리는 일부 프로그램을 작성할 때 객체가 처음으로 구성되는 한 후속 작업이 객체에 대한 다른 작업을 직접 수행할 것이라고 기대하는 경우가 많습니다. 실제로 각 클래스는 다음과 같습니다. 생성 객체 이후에 객체는 메서드나 속성을 호출할 수 있습니다. 이는 가장 기본적인 객체 지향 접근 방식입니다. 그러나 특히 MVC 모드의 프레임워크 개발 프로그램에 적용될 때 일부 프레임워크 컬렉션을 연구하면 컨트롤러에 많은 작업이 있다는 것을 알게 될 것입니다. 이는 우리가 컨트롤러에서 많은 메서드라고 부르는 것입니다. 컨트롤러가 트랜잭션 개체의 작업을 제어할 때 개체를 구성하고 데이터 수집을 작업하는 데 많은 작업이 있을 것입니다. 그러나 매번 개체를 구성하기 위해 NEW 메서드에 의존하는 경우에도 마찬가지입니다. 이번에는 자신의 기억 공간에 대한 부담이 늘어납니다. 새로운 객체를 생성한다는 것은 의심할 여지없이 새로운 메모리 공간을 할당하는 것을 의미하기 때문입니다. 그러나 실제로 동일한 객체 작업의 연속이 필요한 경우에는 이미 생성된 객체를 찾아 호출하는 것이 의심할 여지 없이 매우 좋은 생각입니다. 소위 동일한 개체의 작업이 계속되는 것은 실제로 설명하기 쉽습니다. 예를 들어 데이터 모델 A를 추가하고 삭제하는 등의 작업이 포함된 컨트롤러 클래스를 컨트롤러 A로 구성하면 제어 작업은 다음과 같습니다. 규칙에 따라 일반적으로 프레임세트의 단일 지점 입력 원리를 사용하여 라우팅 배포자 프로그램을 통해 컨트롤러 A를 찾지만 actionAdd 또는 actionDelete에 대한 별도의 호출이 있으며 두 작업 모두 존재한다고 가정합니다. 모델 A의 데이터 작업의 경우 각 작업은 규칙에 따라 데이터 개체를 구성한 다음 SQL을 호출하여 데이터베이스 작업을 수행해야 합니다. $a=new A() 명령문 형식에서 두 작업은 실제로 두 개의 개체를 생성하며 동시에 두 배의 메모리 공간을 차지합니다. 동일한 사람에게 두 개의 작업을 수행하도록 요청하는 것이라고 상상해 보십시오. 개인이 두 가지 일을 따로 하는 걸까요? 당연하게도 이런 상황에서는 리소스가 낭비되고, 작업이 너무 많으면 많은 양의 개체 리소스가 메모리를 차지하게 되어 시스템 성능이 심각하게 저하됩니다. 결국 심각한 충돌로 이어집니다.

사실 우리는 많은 프로그램을 작성할 때 기능을 완성하는 기술은 가장 기본적인 부분일 뿐이라는 점을 거듭 강조해왔습니다. 좋은 프로그램이나 웹사이트를 위해 연구해야 할 것은 기능적인 문제뿐만 아니라, 하지만 더 중요한 것은 전반적인 성능, 특히 대규모 유틸리티 중심 프로그램의 경우 매우 중요합니다. 프레임 컬렉션은 주소 참조를 적절하게 사용하는 데 능숙하므로 이에 대한 좋은 예입니다. 하나의 개체로 처리할 수 있는 작업이 있는 경우 하나의 개체에서 처리하도록 하고 다른 범주의 다른 개체를 위한 충분한 공간을 남겨둡니다.

프레임워크 컬렉션이 객체 리소스 재사용 문제를 해결하는 가장 좋은 방법은 전역 변수를 사용하는 것입니다. 일반적으로 객체가 처음 생성될 때 전역 변수에 로드합니다. 등록된 객체라고도 부를 수 있으므로 앞으로 객체에 대한 메서드 호출을 고려할 때 이 클래스의 객체가 전역 변수에 있는지, 즉 객체가 등록되었는지 직접 확인하겠습니다. 존재하는 경우 이 클래스의 객체를 직접 반환하고 참조용으로 주소를 알려줍니다. 이런 방식으로 객체 주소 참조를 구현하는 것은 쉽습니다. 모든 객체 변수가 동일한 메모리 공간을 가리키도록 생성되면 지금은 이름만 다를 뿐 실제로는 동일한 객체라고 합니다.

따라서 다음과 같은 프로그램 코드를 만들 수 있습니다.

<?php
$GLOBALS[&#39;objects&#39;][&#39;classname&#39;]=null; //是否注册类,类名变量
$GLOBALS[&#39;objects&#39;][&#39;obj&#39;]=null; //对象变量
function & getSingle($classname){
if($GLOBALS[&#39;objects&#39;][&#39;classname&#39;]==$classname){
return $GLOBALS[&#39;objects&#39;][&#39;obj&#39;];
}else
{
$object= new $classname();
$GLOBALS[&#39;objects&#39;][&#39;classname&#39;]=$classname;
$GLOBALS[&#39;objects&#39;][&#39;obj&#39;]=&$object;
return $GLOBALS[&#39;objects&#39;][&#39;obj&#39;];
}
}
class Test{
var $p1;
function Test(){
$this->p1=1;
}
function add()
{
$this->p1++;
}
function show()
{
return $this->p1;
}
}
$test1=&getSingle(&#39;Test&#39;);
$test1->add();
$test2=&getSingle(&#39;Test&#39;);
echo $test2->show();
$test2->add();
$test3=&getSingle(&#39;Test&#39;);
echo $test3->show();
if($test1===$test2)
echo &#39;yes&#39;;
else
echo &#39;no&#39;;
?>
로그인 후 복사

객체가 처음 생성될 때 데이터를 읽기 위한 두 번째 호출은 원본을 기반으로 해야 합니다. 기본 재작업을 통해 $test2가 데이터를 제거하면 결과가 2가 되고, add 작업을 수행한 후 $test3을 다시 읽으면 결과가 3이 되는 것을 알 수 있습니다. 이는 분명히 액션 2가 완료되었기 때문입니다. 이를 통해 단계별 작업에 동일한 개체를 사용하는 것의 이점을 알 수 있습니다. 물론 프레임워크를 사용할 때 위의 상황을 대체하는 이러한 상황이 발생하기 때문입니다. $test1, $test2, $test3 및 해당 작업은 동일한 컨트롤러의 서로 다른 작업에 배치됩니다. 따라서 작업 블록은 서로 독립적이므로 세 가지 개체 변수 중 누가 먼저 트리거되고 누가 먼저 생성합니까? 객체 메모리 공간은 무작위이며 결정됩니다. 첫 번째는 전역 변수에 객체가 등록되어 있는지 확인하고, 객체 주소가 전역 변수에 저장되어 있는지 확인한 후 객체 주소를 비교하여 접근하는 것입니다.


원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!