ස්වයංව භාවිතා කළ යුත්තේ කවදාද?


2003

PHP 5 හි, භාවිතා කිරීම selfසහ අතර ඇති වෙනස කුමක්ද?$this කුමක්ද?

සෑම එකක්ම සුදුසු වන්නේ කවදාද?



මම අහන්න යන්නේ අතර ඇති වෙනස කුමක්ද: cont A; $ this-> A සහ ​​self :: A
timmz

Answers:


1736

කෙටි පිළිතුර

$thisවත්මන් වස්තුව වෙත යොමු වීමට භාවිතා කරන්න . selfවත්මන් පන්තිය වෙත යොමු වීමට භාවිතා කරන්න . වෙනත් වචන වලින් කිවහොත්, $this->memberස්ථිතික නොවන සාමාජිකයින් self::$memberසඳහා භාවිතා කරන්න , ස්ථිතික සාමාජිකයන් සඳහා භාවිතා කරන්න .

සම්පූර්ණ පිළිතුර

මෙහි උදාහරණයක් වන්නේ නිවැරදි භාවිතය $thisහා selfස්ථිතික නොවන හා ස්ථිතික ආකාරයට විචල්යයන් දැක්විය සඳහා:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo $this->non_static_member . ' '
           . self::$static_member;
    }
}

new X();
?>

මෙහි උදාහරණයක් වන්නේ වැරදි භාවිතය $thisහා selfස්ථිතික නොවන හා ස්ථිතික ආකාරයට විචල්යයන් දැක්විය සඳහා:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo self::$non_static_member . ' '
           . $this->static_member;
    }
}

new X();
?>

මෙහි උදාහරණයක් වන්නේ බහුරූපතාෙව් සමග $thisසාමාජික කාර්යයන් සඳහා:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        $this->foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

මෙහි උදාහරණයක් වන්නේ බහුරූපී හැසිරීම මර්දනය භාවිතා selfසාමාජික කාර්යයන් සඳහා:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        self::foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

අදහස නම් වත්මන් වස්තුවේ නිශ්චිත වර්ගය කුමක් වුවත් $this->foo()එහි foo()සාමාජිකයාගේ ක්‍රියාකාරිත්වය හැඳින්වීමයි . වස්තුව නම් type X, එය මෙසේ කියයි X::foo(). වස්තුව නම් type Y, එය කැඳවයි Y::foo(). නමුත් ස්වයං :: foo () සමඟ X::foo()සැමවිටම හැඳින්වේ.

Http://www.phpbuilder.com/board/showthread.php?t=10354489 වෙතින් :

විසින් http://board.phpbuilder.com/member.php?145249-laserlight


330
මෙම පිළිතුර ඕනෑවට වඩා සරල ය. වෙනත් පිළිතුරු වල පෙන්වා ඇති පරිදි , වත්මන් පන්තියට යොමු කිරීම සඳහා selfවිෂය පථ විභේදන ක්‍රියාකරු ::සමඟ භාවිතා කරයි; ස්ථිතික හා ස්ථිතික නොවන සන්දර්භයන්හි මෙය කළ හැකිය. මීට අමතරව, $thisස්ථිතික ක්‍රම ඇමතීමට භාවිතා කිරීම සම්පූර්ණයෙන්ම නීතිමය ය (නමුත් ක්ෂේත්‍ර යොමු කිරීම නොවේ).
Artefacto

50
ඔබ 5.3+ හි සිටී නම් ස්ථිතික :: වෙනුවට :: ස්වයං භාවිතා කිරීම ගැනද සලකා බලන්න. එය ඔබට වෙනත් ආකාරයකින් කිව නොහැකි හිසරදයක් ඇති කළ හැකිය, ඊට හේතුව සඳහා මගේ පිළිතුර පහත බලන්න.
Sqoo

25
-1. මෙම පිළිතුර නොමඟ යවන සුළුය, වැඩි විස්තර සඳහා අනෙක් පිළිතුරු කියවන්න.
පැසීරියර්

6
එය ඕනෑවට වඩා සරල කළ හැකි නමුත් එය මගේ හිස පුපුරා නොයා මගේ මූලික මට්ටමේ ප්‍රශ්නයට පිළිතුරු දුන්නේය. මට තව දුරටත් ප්‍රයෝජනවත් යැයි හැඟුණු තවත් තොරතුරු කිහිපයක් මට ලැබුණි, නමුත් දැනට මම උත්සාහ කරන්නේ මගේ පන්ති ගුණාංග $ this-> ගුණාංගයෙන් සහ පන්ති නියතයන් ස්වයං :: නියතයෙන් පහර දුන්නේ මන්දැයි සොයා ගැනීමටයි. මෙය මට වඩා හොඳින් තේරුම් ගැනීමට උපකාරී විය
MydKnight

කුමක් ගැනද $this::?
ජේම්ස්

743

ස්වයං පදය යනු හුදෙක් 'වත්මන් පන්තියට' යොමු නොවේ , අවම වශයෙන් ස්ථිතික සාමාජිකයින්ට ඔබව සීමා කරන ආකාරයකින් නොවේ. ස්ථිතික නොවන සාමාජිකයෙකුගේ සන්දර්භය තුළ self, vtable මඟ හැරීමේ මාර්ගයක් ද සපයයි ( vti on vtable බලන්න , වත්මන් වස්තුව සඳහා ). parent::methodName()ශ්‍රිතයක දෙමව්පියන්ගේ අනුවාදය ඇමතීමට ඔබට භාවිතා කළ හැකි සේම self::methodName(), ක්‍රමවේදයක් ක්‍රියාත්මක කිරීම සඳහා වර්තමාන පන්ති ඇමතීමටද ඔබට ඇමතිය හැකිය .

class Person {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }

    public function getTitle() {
        return $this->getName()." the person";
    }

    public function sayHello() {
        echo "Hello, I'm ".$this->getTitle()."<br/>";
    }

    public function sayGoodbye() {
        echo "Goodbye from ".self::getTitle()."<br/>";
    }
}

class Geek extends Person {
    public function __construct($name) {
        parent::__construct($name);
    }

    public function getTitle() {
        return $this->getName()." the geek";
    }
}

$geekObj = new Geek("Ludwig");
$geekObj->sayHello();
$geekObj->sayGoodbye();

මෙය ප්‍රතිදානය කරනු ඇත:

හෙලෝ, මම ලුඩ්විග් ගීක්
පුද්ගලයා ලුඩ්විග් සිට ආයුබෝවන්

sayHello()$thisදර්ශකය භාවිතා කරයි , එබැවින් vtable ඇමතීමට කැඳවනු Geek::getTitle()ලැබේ. sayGoodbye()භාවිතා කරයි self::getTitle(), එබැවින් vtable භාවිතා නොකෙරේ, Person::getTitle()එය හැඳින්වේ. අවස්ථා දෙකේදීම, අපි ක්ෂණික වස්තුවක ක්‍රමවේදය සමඟ කටයුතු $thisකරන අතර, හැඳින්වෙන ශ්‍රිත තුළ දර්ශකයට ප්‍රවේශය ඇත .


3
ඔබ ව්‍යතිරේකයකට වඩා සාමාන්‍ය රීතියකින් ආරම්භ කළහොත් මෙම පිළිතුර වඩාත් හොඳ වනු ඇත. එය තාක්ෂණික විශේෂ ise තාවයෙන් නොව ශෛලිය පිළිබඳ කාරණයකි. ස්වයං :: සහ $ this-> අතර වෙනස පිළිබඳව මා මෙතෙක් දැක ඇති හොඳම උදාහරණය මෙයයි, නමුත් පළමුව සංකල්පයක් ප්‍රතික්ෂේප කිරීමෙන් එය සැඟවීම ලැජ්ජාවකි.
adjwilli

3
jadjwilli: ඇයි ඒ නරක විලාසිතාව? OP හි අපේක්ෂාව (නිබන්ධනය) මුලින් ප්‍රතික්ෂේප කරනු ලැබුවහොත් (ප්‍රතිවිරෝධතා) පසුව පැහැදිලි කිරීම සංස්ලේෂණය ලෙස ලබා දෙන්නේ නම් එය වි ness ානය ඉහළ නංවන්නේ නැද්ද?
හක්රේ

1
"වත්මන් පන්තිය" ඇත්තෙන්ම ගැටළු සහගත බව මට පෙනේ. එම වචන සංයෝජනය self"පිහිටා ඇති පන්තිය " / "පන්ති අර්ථ දැක්වීම යන දෙකම" මෙන්ම "වස්තුවේ පන්තිය" (ඇත්ත වශයෙන්ම වනු ඇත static) යන වචන දෙකෙන්ම තේරුම් ගත හැකිය .
ජකුමි

කුමක් ගැනද $this::?
ජේම්ස්

1
Ames ජේම්ස් - භාවිතා කිරීමට හොඳ හේතුවක් නැත $this::; හැකි සෑම අවස්ථාවක්ම දැනටමත් බහුලව භාවිතා වන සින්ටැක්ස් මගින් ආවරණය කර ඇත. ඔබ අදහස් කරන දේ මත පදනම්ව, භාවිතය $this->, self::හෝ static::.
මෙවලම් සාදන්නා ස්ටීව්

460

භාවිතා නොකරන්න self::, භාවිතා කරන්නstatic::

ස්වයං තවත් අංගයක් ඇත :: එය සඳහන් කිරීම වටී. කරදරකාරී ලෙස self::හැඳින්වෙන්නේ ක්‍රියාත්මක වන මොහොතේ නොව අර්ථ දැක්වීමේ ලක්ෂ්‍යයේ විෂය පථයයි . ක්‍රම දෙකකින් මෙම සරල පන්තිය සලකා බලන්න:

class Person
{

    public static function status()
    {
        self::getStatus();
    }

    protected static function getStatus()
    {
        echo "Person is alive";
    }

}

අප අමතන්නේ නම් Person::status()"පුද්ගලයා ජීවතුන් අතර සිටී". දැන් අපි මෙයින් උරුම වන පන්තියක් කරන විට කුමක් සිදුවේදැයි සලකා බලන්න:

class Deceased extends Person
{

    protected static function getStatus()
    {
        echo "Person is deceased";
    }

}

ඇමතුම Deceased::status()"පුද්ගලයා මියගොස් ඇත" යන්න දැකීමට අපි අපේක්ෂා කරමු. කෙසේ වෙතත් අප දකින දෙය "පුද්ගලයා ජීවතුන් අතර සිටී" යන්නට ඇමතුම අර්ථ දැක්වීමේදී මුල් ක්‍රමවේදය අර්ථ දැක්වීම විෂය පථයේ අඩංගු වේ self::getStatus().

PHP 5.3 ට විසඳුමක් ඇත. මෙම static::යෝජනාව ක්රියාකරු උපකරණ "ප්රමාද ස්ථිතික බන්ධන" ලෙස පන්ති හි විෂය පථය බැඳී තියෙන්නේ බව පවසමින් ක විසිතුරු මගක් වන. ඇති පේළිය වෙනස් status()කිරීමට static::getStatus() හා ප්රතිඵල බලාපොරොත්තු වෙන දේ වේ. PHP හි පැරණි සංස්කරණ වලදී ඔබට මෙය කිරීමට කුඩයක් සොයා ගැනීමට සිදුවේ.

PHP ප්‍රලේඛනය බලන්න

එබැවින් ඇසූ පරිදි නොව ප්‍රශ්නයට පිළිතුරු දීමට ...

$this->වත්මන් වස්තුවට (පන්තියක උදාහරණයක්), පංතියකට static::යොමු වේ


6
පන්ති නියතයන් සඳහා කුමක් කළ යුතුද?
කෙවින් බොන්ඩ්

53
"ඇමතුම මිය ගියේය :: තත්වය ()" පුද්ගලයා මියගොස් ඇත "යනුවෙන් අපි බලාපොරොත්තු වෙමු. නැත. මෙය ස්ථිතික ශ්‍රිත ඇමතුමකි, එබැවින් බහුඅවයවිකතාවයක් නොමැත.
cquezel

2
PHP හි ඇති සියලුම අඩුපාඩු අතරින්, මෙය කිසිසේත් පිස්සු යැයි මම නොසිතමි. වත්මන් පංතියේ ක්‍රමවේදයන් (ඒවා vtable හි සොයා බැලීමට වඩා වෙනස්ව) නියම කිරීමට ඔවුන් කෝඩරයන්ට ඉඩ දෙන්නේ කෙසේද? ඔවුන් එය වෙනස් ලෙස නම් කර තිබේ නම් (සමහර විට ප්‍රමුඛ අවධාරණයන් සහිතව) මෙම අංගය අවශ්‍ය අය එය අවලස්සන යැයි විවේචනය කරනු ඇත. වෙනත් ආකාරයකින්, ඔවුන් භාවිතා කරන ඕනෑම නමක් නම්, එය "උමතු" හැසිරීමක් ලෙස විවේචනය කරන පුද්ගලයින් නිතරම ව්‍යාකූලත්වයට පත්වන බවක් පෙනේ. ක්‍රමයෙන් පිටත් කර යැවීම පවා ක්‍රියාත්මක වන්නේ කෙසේද යන්න නොසලකා හරිනු ඇත.
tne

2
උදාහරණය මට ව්‍යාකූල බවක් පෙනේ: මම getStatusක්‍රමයක් දකින්නේ පන්තියක් සඳහා නොව පන්ති අවස්ථාවක් සඳහා ය.
ජැනිස් එල්මරිස්

1
QSqoo - "ස්වයං භාවිතා නොකරන්න :: ස්ථිතික :: භාවිතා කිරීම" කිරීම අමුතු කරුණකි - ඒවා හිතාමතාම එකම මෙහෙයුමක් නොවේ. මම හිතන්නේ ඔබ සැබවින්ම කරන කාරණය "ඔබ 'ස්වයං ::' යන්නට වඩා 'මයික්ලාස් ::' යන සැබෑ පන්තියේ නම භාවිතා කරන්නේ නම් එය වඩාත් පැහැදිලි වේ. එනම්, ඔබට හැසිරීම අවශ්‍ය නම් self::ඔබට එය ලබා ගත හැකිය, අඩු අවුල් සහගත ලෙස, නිශ්චිත පන්තියේ නම භාවිතා කිරීමෙන්, උදා MyClass::.
මෙවලම් සාදන්නා ස්ටීව්

248

අපි selfඑදිරිව එදිරිව කතා කරන විට අප කතා කරන්නේ කුමක් දැයි තේරුම් ගැනීමට නම් $this, ඇත්ත වශයෙන්ම සංකල්පීය හා ප්‍රායෝගික මට්ටමින් සිදුවන්නේ කුමක්ද යන්න පිළිබඳව සොයා බැලිය යුතුය. කිසිම පිළිතුරක් සුදුසු පරිදි කරන බව මට දැනෙන්නේ නැත, එබැවින් මෙන්න මගේ උත්සාහය.

පංතියක් සහ වස්තුවක් යනු කුමක්ද යන්න ගැන කතා කිරීමෙන් ආරම්භ කරමු .

පංති සහ වස්තු, සංකල්පමය වශයෙන්

ඒ නිසා, වන වන පන්තියට ? බොහෝ අය එය අර්ථ දක්වන්නේ වස්තුවක් සඳහා සැලැස්මක් හෝ අච්චුවක් ලෙස ය. ඇත්ත වශයෙන්ම, ඔබට PHP හි පන්ති ගැන වැඩිදුර කියවිය හැකිය . යම් තාක් දුරකට එය සැබවින්ම එයයි. පංතියක් දෙස බලමු:

class Person {
    public $name = 'my name';
    public function sayHello() {
        echo "Hello";
    }
}

ඔබට කිව හැකි පරිදි, එම පන්තියේ දේපලක් ඇති අතර එය හැඳින්වෙන $nameක්‍රමයක් (ශ්‍රිතයක්) sayHello()ඇත.

ඒක ඉතා බව සටහන් කිරීම වැදගත් පන්ති ස්ථිතික ව්යූහයක්. එයින් අදහස් වන්නේ පංතිය Person, වරක් නිර්වචනය කළ විට, ඔබ එය දෙස බලන සෑම තැනකම එක හා සමාන බවයි.

අනෙක් අතට වස්තුවක් යනු පන්තියක උදාහරණයක් ලෙස හැඳින්වේ . එහි තේරුම නම්, අපි පංතියේ "සැලැස්ම" ගෙන ගතික පිටපතක් සෑදීමට එය භාවිතා කිරීමයි. මෙම පිටපත දැන් විශේෂයෙන් එය ගබඩා කර ඇත්තේ විචල්ය සමඟ බැඳී ඇත. එම නිසා යම් වෙනස් උදාහරණයක් බව උදාහරණයක් දේශීය වේ.

$bob = new Person;
$adam = new Person;
$bob->name = 'Bob';
echo $adam->name; // "my name"

අපි ක්‍රියාකරු භාවිතා කරමින් පන්තියක නව අවස්ථා නිර්මාණය කරමු new.

එබැවින්, පංතියක් යනු ගෝලීය ව්‍යුහයක් බවත්, වස්තුවක් යනු දේශීය ව්‍යුහයක් බවත් අපි කියමු. ඒ විහිලු ->වාක්‍ය ඛණ්ඩය ගැන කරදර නොවන්න , අපි තව ටිකකින් ඒ තුළට යන්නෙමු.

අප කතා කළ යුතු තවත් දෙයක් නම්, නිදසුනක් විශේෂිත පන්තියක් දැයි අපට පරීක්ෂා කළ හැකිය instanceof: $bob instanceof Personඑම $bobඅවස්ථාව Personපන්තිය හෝ දරුවෙකු භාවිතා කර සාදන ලද්දේ නම් එය බූලියන් ආපසු ලබා දෙයි Person.

රාජ්‍යය නිර්වචනය කිරීම

එබැවින් පංතියක ඇත්ත වශයෙන්ම අඩංගු දේ ගැන ටිකක් හාරා බලමු. පන්තියක අඩංගු "දේවල්" වර්ග 5 ක් ඇත:

  1. ගුණාංග - මේවා එක් එක් අවස්ථාවන්හි අඩංගු විචල්‍යයන් ලෙස සිතන්න.

    class Foo {
        public $bar = 1;
    }
  2. ස්ථිතික ගුණාංග - මේවා පන්ති මට්ටමින් බෙදාගන්නා විචල්‍යයන් ලෙස සිතන්න. සෑම අවස්ථාවකින්ම ඒවා කිසි විටෙකත් පිටපත් නොකරන බව අදහස් වේ.

    class Foo {
        public static $bar = 1;
    }
  3. ක්‍රම - මේවා එක් එක් අවස්ථාවන්හි අඩංගු වන කාර්යයන් වේ (සහ අවස්ථා මත ක්‍රියාත්මක වේ).

    class Foo {
        public function bar() {}
    }
  4. ස්ථිතික ක්‍රම - මේවා සමස්ත පන්තිය පුරා බෙදාගන්නා කාර්යයන් වේ. ඔවුන් කරන්නේ නෑ ස්ථිතික ගුණ පමණක් ඒ වෙනුවට අවස්ථා මත ක්රියාත්මක කිරීමට, නමුත්.

    class Foo {
        public static function bar() {}
    }
  5. නියත - පංතිය නියත සම්මත කරගත්තේය. මෙහි ගැඹුරට නොයෑම, නමුත් සම්පූර්ණත්වය සඳහා එකතු කිරීම:

    class Foo {
        const BAR = 1;
    }

එබැවින් මූලික වශයෙන්, අපි ස්ථිතිකය පිළිබඳ "ඉඟි" භාවිතා කරමින් පංතිය සහ වස්තු බහාලුම් පිළිබඳ තොරතුරු ගබඩා කර තබන්නෙමු. එමඟින් තොරතුරු බෙදාගෙන තිබේද (සහ ඒ නිසා ස්ථිතිකද) නැද්ද යන්න හඳුනා ගනී.

රාජ්ය සහ ක්රම

ක්‍රමයක් තුළ, වස්තුවක උදාහරණය $thisවිචල්‍යය මගින් නිරූපණය කෙරේ . එම වස්තුවෙහි වර්තමාන තත්වය පවතින අතර, ඕනෑම දේපලක් විකෘති කිරීම (වෙනස් කිරීම) එම අවස්ථාවෙහි වෙනසක් ඇති කරයි (නමුත් අනෙක් ඒවා නොවේ).

ක්‍රමයක් ස්ථිතික ලෙස හැඳින්වුවහොත් $thisවිචල්‍යය නිර්වචනය නොවේ . මෙයට හේතුව ස්ථිතික ඇමතුමක් හා සම්බන්ධ කිසිදු අවස්ථාවක් නොමැති වීමයි.

මෙහි ඇති සිත්ගන්නා කරුණ නම් ස්ථිතික ඇමතුම් ලබා ගන්නා ආකාරයයි. එබැවින් අපි රාජ්යයට ප්රවේශ වන ආකාරය ගැන කතා කරමු:

රාජ්යයට ප්රවේශ වීම

දැන් අපි එම තත්වය ගබඩා කර ඇති නිසා, අපි එයට ප්‍රවේශ විය යුතුයි. මෙම ටිකක් වෙනත් ඕනැම (හෝ ලබා ගත හැක ආකාරය ටිකක් වැඩි), එසේ මත වාදයන් දෙකකට ගේ භේදය මෙම කරමු: නිදසුනක් / පන්ති (සාමාන්ය කාර්යය ඇමතුමක්, හෝ ගෝලීය විෂය පථය සිට කියන්නේ) පිටත, සහ අවස්ථා ඇතුළත සිට / පන්තිය (වස්තුව පිළිබඳ ක්‍රමයක් තුළ සිට).

අවස්ථාවක් / පන්තියකට පිටතින්

නිදසුනක් / පන්තියක පිටතින්, අපගේ නීති තරමක් සරල හා පුරෝකථනය කළ හැකිය. අපට ක්‍රියාකරුවන් දෙදෙනෙකු සිටින අතර, අපි නිදසුනක් හෝ පන්ති ස්ථිතිකයක් සමඟ කටයුතු කරන්නේ නම් එක් එක් කෙනා වහාම අපට කියයි:

  • ->- වස්තු-ක්‍රියාකරු - අප සැමවිටම උදාහරණයකට ප්‍රවේශ වන විට මෙය භාවිතා වේ.

    $bob = new Person;
    echo $bob->name;

    ඇමතීම Person->fooතේරුමක් නැති බව සැලකිල්ලට ගැනීම වැදගත්ය ( Personපංතියක් බැවින්, උදාහරණයක් නොවේ). එමනිසා, එය විග්‍රහ දෝෂයකි.

  • ::- විෂය පථය-විභේදන-ක්‍රියාකරු - මෙය සැමවිටම පන්ති ස්ථිතික දේපලකට හෝ ක්‍රමයකට ප්‍රවේශ වීමට භාවිතා කරයි.

    echo Foo::bar()

    මීට අමතරව, අපට වස්තුවක් මත ස්ථිතික ක්‍රමයක් එකම ආකාරයකින් හැඳින්විය හැකිය:

    echo $foo::bar()

    ඒක අතිශය අපි මේ කරන විට බව සටහන් කිරීම වැදගත් පිටත සිට , වස්තුව ගේ උදාහරණයක් සඟවා ඇත bar()ක්රමය. එය ක්‍රියාත්මක වීමට හරියටම සමාන බව තේරුම:

    $class = get_class($foo);
    $class::bar();

එබැවින් $thisස්ථිතික ඇමතුමෙහි අර්ථ දක්වා නොමැත.

අවස්ථාවක් / පන්තියක් ඇතුළත සිට

මෙහි තත්වය ටිකක් වෙනස් වේ. එකම ක්‍රියාකරුවන් භාවිතා කරන නමුත් ඒවායේ අර්ථය සැලකිය යුතු ලෙස බොඳ වේ.

මෙම වස්තුව-ක්රියාකරු -> වස්තුව ගේ උදාහරණයක් රාජ්ය ඇමතුම් ගැනීමට තවමත් භාවිතා කරයි.

class Foo {
    public $a = 1;
    public function bar() {
        return $this->a;
    }
}

මෙම ඇමතුම් bar()මත ක්රමය $foo(ක උදාහරණයක් Fooවස්තුව-ක්රියාකරු භාවිතා කරමින්): $foo->bar()පිළිබඳ කාරණයේ අනුවාදය හේතු වනු ඇත $a.

ඉතින් අපි බලාපොරොත්තු වෙන්නේ එහෙමයි.

::ක්‍රියාකරුගේ අර්ථය වෙනස් වුවද. එය වත්මන් ශ්‍රිතයට ඇමතුමේ සන්දර්භය මත රඳා පවතී:

  • ස්ථිතික සන්දර්භයක් තුළ

    ස්ථිතික සන්දර්භයක් තුළ, භාවිතා කරන ඕනෑම ඇමතුමක් ::ස්ථිතික වේ. උදාහරණයක් බලමු:

    class Foo {
        public function bar() {
            return Foo::baz();
        }
        public function baz() {
            return isset($this);
        }
    }

    කරන මා ෙවත පවරා Foo::bar()ඇති කියනු ඇත baz()statically ක්රමය හා, එම නිසා $thisඇත නොහැකි ජීවත් වීමට. PHP (5.3+) හි මෑත සංස්කරණ වලදී මෙය E_STRICTදෝෂයක් ඇති කරන බව සඳහන් කිරීම වටී , මන්ද අපි ස්ථිතික නොවන ක්‍රම සංඛ්‍යාත්මකව අමතන්නෙමු.

  • උදාහරණ සන්දර්භයක් තුළ

    අනෙක් අතට, සන්දර්භය තුළ, භාවිතා කරන ඇමතුම්, ඇමතුම ::ලබන්නා මත රඳා පවතී (අප අමතන ක්‍රමය). ක්‍රමය ලෙස අර්ථ දක්වා ඇත්නම් static, එය ස්ථිතික ඇමතුමක් භාවිතා කරනු ඇත. එය එසේ නොවේ නම්, එය උදාහරණ තොරතුරු ඉදිරිපත් කරයි.

    එබැවින්, ඉහත කේතය දෙස බලන විට, ඇමතුම් $foo->bar()නැවත ලැබෙනු ඇත true, මන්ද “ස්ථිතික” ඇමතුම සිදුවන්නේ සන්දර්භය තුළ ය.

තේරුමක් තිබේද? එසේ සිතුවේ නැත. එය අවුල් සහගත ය.

කෙටිමං වචන

පංති නාම භාවිතා කරමින් සෑම දෙයක්ම එකට බැඳීම තරමක් අපිරිසිදු බැවින්, විෂය පථය විසඳීම පහසු කිරීම සඳහා PHP මූලික “කෙටිමං” වචන 3 ක් සපයයි.

  • self- මෙය වර්තමාන පන්තියේ නමට යොමු වේ. ඒ නිසා self::baz()ම ය Foo::baz()තුළ Fooපන්ති (එය මත ඕනෑම ක්රමයක්).

  • parent - මෙය වර්තමාන පන්තියේ මවුපියන්ට යොමු කරයි.

  • static- මෙය හැඳින්වෙන්නේ පන්තියට ය. උරුමයට ස්තූතියි, ළමා පන්ති වලට ක්‍රම සහ ස්ථිතික ගුණාංග අභිබවා යා හැකිය. එබැවින් staticපන්ති නාමයක් වෙනුවට ඔවුන් ඇමතීමෙන් වත්මන් මට්ටමට වඩා ඇමතුම පැමිණියේ කොතැනින්ද යන්න නිරාකරණය කිරීමට අපට ඉඩ සලසයි.

උදාහරණ

මෙය තේරුම් ගැනීමට ඇති පහසුම ක්‍රමය නම් උදාහරණ කිහිපයක් බැලීම ආරම්භ කිරීමයි. අපි පන්තියක් තෝරා ගනිමු:

class Person {
    public static $number = 0;
    public $id = 0;
    public function __construct() {
        self::$number++;
        $this->id = self::$number;
    }
    public $name = "";
    public function getName() {
        return $this->name;
    }
    public function getId() {
        return $this->id;
    }
}

class Child extends Person {
    public $age = 0;
    public function __construct($age) {
        $this->age = $age;
        parent::__construct();
    }
    public function getName() {
        return 'child: ' . parent::getName();
    }
}

දැන්, අපි ද මෙහි උරුමය දෙස බලමු. මෙය නරක වස්තු ආකෘතියක් බව මොහොතකට නොසලකා හරින්න, නමුත් අපි මේ සමඟ සෙල්ලම් කරන විට කුමක් සිදුවේදැයි බලමු:

$bob = new Person;
$bob->name = "Bob";
$adam = new Person;
$adam->name = "Adam";
$billy = new Child;
$billy->name = "Billy";
var_dump($bob->getId()); // 1
var_dump($adam->getId()); // 2
var_dump($billy->getId()); // 3

එබැවින් හැඳුනුම් කවුන්ටරය අවස්ථා දෙකෙහිම සහ ළමයින් අතර බෙදා selfගැනේ static(අප එයට ප්‍රවේශ වීමට භාවිතා කරන නිසා. අප භාවිතා කළේ නම් , අපට එය ළමා පන්තියකදී අභිබවා යා හැකිය).

var_dump($bob->getName()); // Bob
var_dump($adam->getName()); // Adam
var_dump($billy->getName()); // child: Billy

අපි සෑම විටම Person::getName() උදාහරණ ක්‍රමය ක්‍රියාත්මක කරන බව සලකන්න . නමුත් අපි එය භාවිතා parent::getName()කරන්නේ එක් අවස්ථාවකදී (ළමා නඩුව). මෙම ප්‍රවේශය බලවත් වන්නේ මෙයයි.

අවවාදයේ වචනය # 1

නිදසුනක් භාවිතා කරන්නේද යන්න තීරණය කරන්නේ ඇමතුම් සන්දර්භය බව සලකන්න. එබැවින්:

class Foo {
    public function isFoo() {
        return $this instanceof Foo;
    }
}

සැමවිටම සත්‍ය නොවේ .

class Bar {
    public function doSomething() {
        return Foo::isFoo();
    }
}
$b = new Bar;
var_dump($b->doSomething()); // bool(false)

දැන් එය ඇත්තෙන්ම අමුතුයි. අපි වෙනත් පංතියක් අමතන්නෙමු, නමුත් ක්‍රමයට $thisසම්මත Foo::isFoo()වන අවස්ථාව මෙයයි $bar.

මෙය සියලු ආකාරයේ දෝෂ සහ සංකල්පීය WTF-ery වලට හේතු විය හැක. මා අතිශයින් වැළකී යෝජනා කියලා ඒ නිසා ::එම අතාත්වික "කෙටි-සැපයුම අත්හිටුවන" ප්රධාන වචන තුනක් (හැර අන් කිසිවකට උදාහරණයක් ක්රම තුළ සිට ක්රියාකරු static, selfසහ parent).

අවවාදයේ වචනය # 2

ස්ථිතික ක්‍රම සහ ගුණාංග සෑම කෙනෙකුටම බෙදා දෙන බව සලකන්න. එමඟින් ඒවා මූලික වශයෙන් ගෝලීය විචල්‍යයන් බවට පත් කරයි. ග්ලෝබල් සමඟ එන එකම ගැටළු සමඟ. එබැවින් තොරතුරු සැබවින්ම ගෝලීය වීම ගැන ඔබට සැපපහසු නම් මිස ස්ථිතික ක්‍රම / දේපලවල තොරතුරු ගබඩා කිරීමට මම සැබවින්ම පසුබට වෙමි.

අවවාදයේ වචනය # 3

පොදුවේ ඔබට staticඒ වෙනුවට භාවිතා කිරීමෙන් ප්‍රමාද-ස්ථිතික-බන්ධන ලෙස හැඳින්වෙන දේ භාවිතා කිරීමට අවශ්‍ය වනු ඇත self. නමුත් ඒවා එකම දෙයක් නොවන බව සලකන්න, එබැවින් "සැමවිටම භාවිතා කිරීම staticවෙනුවට selfකෙටි දැක්මක් ඇත. ඒ වෙනුවට, ඔබට කළ යුතු ඇමතුම නවතා සිතා බලන්න, ඔබට ස්ථිතික විසඳුමක් ඉක්මවා යාමට ළමා පන්තිවලට අවශ්‍ය නම් සිතන්න අමතන්න.

ටීඑල් / ඩී.ආර්

ඉතා නරකයි, ආපසු ගොස් එය කියවන්න. එය ඉතා දිගු විය හැකි නමුත් එය සංකීර්ණ මාතෘකාවක් බැවින් එය දිගු වේ

TL / DR # 2

හරි හොදයි. කෙටියෙන් කිවහොත්, selfඅදාල කිරීමට භාවිතා වත්මන් පන්ති නම ලෙස එහිදී පන්තිය, තුළ $thisවත්මන් වස්තුව යනු උදාහරණයක් . selfඑය කෙටි කප්පාදුවක් / පිටපතක් බව සලකන්න . ඔබට එය ඔබගේ පන්තියේ නම සමඟ ආරක්ෂිතව ප්‍රතිස්ථාපනය කළ හැකි අතර එය හොඳින් ක්‍රියාත්මක වේ. නමුත් $thisගතික විචල්‍යයක් වන අතර එය කල්තියා තීරණය කළ නොහැක (එය ඔබේ පන්තිය පවා නොවිය හැක).

TL / DR # 3

වස්තු-ක්‍රියාකරු ( ->) භාවිතා කරන්නේ නම් , ඔබ සැමවිටම දන්නවා ඔබ උදාහරණයක් සමඟ කටයුතු කරන බව. විෂය පථය-විභේදන-ක්‍රියාකරු භාවිතා කරන්නේ නම් ( ::), ඔබට සන්දර්භය පිළිබඳ වැඩි විස්තර අවශ්‍ය වේ (අප දැනටමත් වස්තු-සන්දර්භයක සිටිනවාද? අප වස්තුවකට පිටතින් සිටිනවාද? ආදිය).



හොඳයි ... $thisඔබ "දැඩි ප්‍රමිති" අනුගමනය කරන්නේ නම් සහ ස්ථිතික ලෙස අර්ථ දක්වා නැති ක්‍රම සංඛ්‍යාත්මකව නොකියන්නේ නම් නිර්වචනය නොකෙරේ. ඔබ මෙහි පැහැදිලි කළ ප්‍රති result ලය මට පෙනේ: 3v4l.org/WeHVM එකඟ විය, ඇත්තෙන්ම අමුතුයි.
මාර්ක් අචී

2
දීර් description විස්තරය මුළුමනින්ම කියවීමෙන් පසු, එය ඉහළට ඔසවා තැබීමට නැවත ඉහළට අනුචලනය කිරීමට මට කම්මැලි විය. විහිළුවක් කරමින්, මම එය ඉහළට ඔසවා තැබුවෙමි: ඩී. ස්තූතියි මෙය ඉතා ප්‍රයෝජනවත්.
Mr_Green

3
ස්වයං :: $ දේපල සහ ස්වයං :: දේපල අතර වෙනස පිළිබඳව පැහැදිලි පැහැදිලි කිරීමක් එක් කිරීම සතුටක්; මම හිතන්නේ එයත් තරමක්
ව්‍යාකූලයි

1
WoC # 1 PHP 7 සිට වෙනස් ලෙස හැසිරේ. සංඛ්‍යානමය වශයෙන් Foo::isFoo()හැඳින්වෙන පරිදි , $thisඅර්ථ දැක්වෙන්නේ නැත. මගේ මතය අනුව එය වඩාත් බුද්ධිමත් හැසිරීමකි. - තවත් විවිධ ප්රතිඵලයක් නම් ලබා දී ඇත Barසිට දීර්ඝ කිරීමට වූහ Foo. එවිට ඇමතුම Foo::isFoo()ඇත්ත වශයෙන්ම උදාහරණ සන්දර්භය තුළ වේ (PHP7 සඳහා විශේෂිත නොවේ).
කොන්ට්‍රොල්ෆ්‍රීක්

117

self($ ස්වයං නොවේ) යන්නෙන් අදහස් කරන්නේ පන්තියේ වර්ගයයි , එහිදී පන්තියේ $thisවත්මන් අවස්ථාව දක්වයි . selfස්ථිතික සාමාජික විචල්‍යයන් වෙත ප්‍රවේශ වීමට ඔබට ඉඩ දීම සඳහා ස්ථිතික සාමාජික ශ්‍රිතවල භාවිතය සඳහා වේ. $thisස්ථිතික නොවන සාමාජික ශ්‍රිතවල භාවිතා වන අතර එය සාමාජික ශ්‍රිතය හැඳින්වූ පන්තියේ උදාහරණයකි.

නිසා thisයම් වස්තුවක්, ඔබ වගේ භාවිතා කරන්න:$this->member

selfවස්තුවක් නොවන නිසා , එය මූලිකවම වර්තමාන පන්තියට ස්වයංක්‍රීයව යොමු වන වර්ගයකි, ඔබ එය භාවිතා කරන්නේ:self::member


97

$this-> පන්තියේ විචල්යයන් (සාමාජික විචල්යයන්) හෝ ක්රමවල නිශ්චිත අවස්ථාවක් යොමු කිරීමට භාවිතා කරයි.

Example: 
$derek = new Person();

re ඩෙරෙක් දැන් පුද්ගලයාගේ නිශ්චිත අවස්ථාවකි. සෑම පුද්ගලයෙකුටම පළමු නම සහ අවසාන නම ඇත, නමුත් $ ඩෙරෙක්ට නිශ්චිත පළමු නම සහ අවසාන නම ඇත (ඩෙරෙක් මාටින්). $ ඩෙරෙක් උදාහරණය තුළ, අපට ඒවා $ this-> first_name සහ $ this-> last_name ලෙස හැඳින්විය හැකිය.

ClassName :: භාවිතා කරන්නේ එම වර්ගයේ පන්තිය සහ එහි ස්ථිතික විචල්‍යයන් වන ස්ථිතික ක්‍රම වෙතය. එය උදව් කරන්නේ නම්, ඔබට "ස්ථිතික" යන වචනය "හවුල්" සමඟ මානසිකව ආදේශ කළ හැකිය. ඒවා බෙදාගෙන ඇති නිසා, ඔවුන්ට $ මෙය යොමු කළ නොහැක, එය නිශ්චිත අවස්ථාවක් (බෙදාගෙන නැත). ස්ථිතික විචල්‍යයන් (එනම් ස්ථිතික $ db_connection) යම් ආකාරයක වස්තුවක සියලු අවස්ථා අතර බෙදා ගත හැකිය. උදාහරණයක් ලෙස, සියලුම දත්ත සමුදා වස්තු තනි සම්බන්ධතාවයක් (ස්ථිතික $ සම්බන්ධතාවය) බෙදා ගනී.

ස්ථිතික විචල්‍යයන් උදාහරණය: අපට තනි සාමාජික විචල්‍යයක් සහිත දත්ත සමුදා පන්තියක් ඇති බව පෙන්වන්න: ස්ථිතික $ num_connections; දැන්, මෙය ඉදිකිරීම්කරු තුළ තබන්න:

function __construct()
{
    if(!isset $num_connections || $num_connections==null)
    {
        $num_connections=0;
    }
    else
    {
        $num_connections++;
    }
}

වස්තූන් හට ඉදිකිරීම්කරුවන් සිටිනවා සේම, ඒවාට විනාශ කරන්නන් ද ඇත, ඒවා වස්තුව මිය ගිය විට හෝ සැකසූ විට ක්‍රියාත්මක වේ:

function __destruct()
{
    $num_connections--;
}

අපි නව අවස්ථාවක් නිර්මාණය කරන සෑම අවස්ථාවකම එය අපගේ සම්බන්ධතා කවුන්ටරය එකකින් වැඩි කරයි. අපි නිදසුනක් භාවිතා කිරීම විනාශ කරන හෝ නතර කරන සෑම අවස්ථාවකම එය සම්බන්ධතා කවුන්ටරය එකකින් අඩු කරයි. මේ ආකාරයට, අප භාවිතා කරන දත්ත සමුදා වස්තුවේ අවස්ථා ගණන නිරීක්ෂණය කළ හැකිය:

echo DB::num_connections;

_ Num_connections ස්ථිතික (බෙදාගෙන ඇති) නිසා, එය සක්‍රීය දත්ත සමුදා වස්තු ගණන පිළිබිඹු කරයි. දත්ත සමුදා පන්තියක සියලු අවස්ථා අතර දත්ත සමුදා සම්බන්ධතා බෙදා ගැනීමට භාවිතා කරන මෙම තාක්ෂණය ඔබ දැක ඇති. මෙය සිදු කරනුයේ දත්ත සමුදා සම්බන්ධතාවය නිර්මාණය කිරීමට බොහෝ කාලයක් ගත වන නිසා එකක් පමණක් නිර්මාණය කර බෙදා ගැනීම වඩාත් සුදුසුය (මෙය සිංගල්ටන් රටාවක් ලෙස හැඳින්වේ).

ස්ථිතික ක්‍රම (එනම් පොදු ස්ථිතික දසුන :: format_phone_number ($ ඉලක්කම්)) භාවිතා කළ හැක්කේ එම වස්තූන්ගෙන් එකක් මුලින්ම ස්ථාපනය නොකර (එනම් ඒවා අභ්‍යන්තරව $ මේ ගැන සඳහන් නොකරයි).

ස්ථිතික ක්‍රම උදාහරණය:

public static function prettyName($first_name, $last_name)
{
    echo ucfirst($first_name).' '.ucfirst($last_name);
}

echo Person::prettyName($derek->first_name, $derek->last_name);

ඔබට පෙනෙන පරිදි, පොදු ස්ථිතික ශ්‍රිත ලස්සන නේම් වස්තුව ගැන කිසිවක් දන්නේ නැත. එය හුදෙක් වස්තුවක කොටසක් නොවන සාමාන්‍ය ශ්‍රිතයක් මෙන් ඔබ පසු කරන පරාමිතීන් සමඟ ක්‍රියා කරයි. එසේනම් අපට එය වස්තුවේ කොටසක් ලෙස තබා ගත නොහැකි නම් කරදර වන්නේ ඇයි?

  1. පළමුව, වස්තූන් වෙත කාර්යයන් ඇමිණීම ඔබට දේවල් සංවිධානාත්මකව තබා ගැනීමට උපකාරී වේ, එබැවින් ඒවා සොයා ගත හැකි ස්ථානය ඔබ දන්නවා.
  2. දෙවනුව, ගැටුම් නම් කිරීම වළක්වයි. විශාල ව්‍යාපෘතියක, ඔබට සංවර්ධකයින් දෙදෙනෙකු getName () කාර්යයන් නිර්මාණය කිරීමට ඉඩ තිබේ. යමෙක් ClassName1 :: getName () නිර්මාණය කරන්නේ නම්, අනෙකා ClassName2 :: getName () නිර්මාණය කරන්නේ නම් එය කිසිසේත්ම ගැටළුවක් නොවේ. ගැටුමක් නැත. ස්ථිතික ක්‍රම!

SELF :: ඔබ යොමු කිරීමට අවශ්‍ය ස්ථිතික ක්‍රමය ඇති වස්තුවෙන් පිටත කේත කරන්නේ නම් , ඔබ එය වස්තුවේ නම භාවිතා කර අමතන්න View :: format_phone_number ($ phone_number); ඔබට යොමු කිරීමට අවශ්‍ය ස්ථිතික ක්‍රමය ඇති වස්තුව තුළ ඔබ කේත කරන්නේ නම් , ඔබට වස්තුවේ නම View :: format_phone_number ($ pn) භාවිතා කළ හැකිය, නැතහොත් ඔබට ස්වයං :: format_phone_number ($ pn) කෙටිමඟ භාවිතා කළ හැකිය.

ස්ථිතික විචල්‍යයන් සඳහා ද මෙයම වේ: උදාහරණය: බලන්න :: templates_path එදිරිව ස්වයං :: templates_path

ඩීබී පන්තිය තුළ, අපි වෙනත් වස්තුවක ස්ථිතික ක්‍රමයක් ගැන සඳහන් කරන්නේ නම්, අපි එම වස්තුවේ නම භාවිතා කරමු: උදාහරණය: සැසිය :: getUsersOnline ();

නමුත් ඩීබී පන්තියට තමන්ගේම ස්ථිතික විචල්‍යය වෙත යොමු වීමට අවශ්‍ය නම්, එය ස්වයං යැයි කියනු ඇත: උදාහරණය: ස්වයං :: සම්බන්ධතාවය;

දේවල් නිරවුල් කිරීමට උපකාරී වන බලාපොරොත්තුව :)


නියම පිළිතුර. මට පෙන්වා දීමට අවශ්‍යයි, ස්ථිතික ලක්ෂණයක් ගැන සඳහන් කිරීමේදී, ඔබ $ලකුණක් භාවිතා කළ යුතුය. උදාහරණයක් ලෙසself::$templates_path
හෙන්රි රයිට්

30

සිට බ්ලොග් :

  • self වත්මන් පන්තියට යොමු වේ
  • self ස්ථිතික ශ්‍රිත ඇමතීමට සහ ස්ථිතික සාමාජික විචල්‍යයන් යොමු කිරීමට භාවිතා කළ හැකිය
  • self ස්ථිතික කාර්යයන් තුළ භාවිතා කළ හැකිය
  • self vtable මඟ හැරීමෙන් බහුමාමක හැසිරීම අක්‍රිය කළ හැකිය
  • $this වත්මන් වස්තුවට යොමු වේ
  • $this ස්ථිතික ශ්‍රිත ඇමතීමට භාවිතා කළ හැකිය
  • $thisස්ථිතික සාමාජික විචල්‍යයන් ඇමතීමට භාවිතා නොකළ යුතුය. selfඒ වෙනුවට භාවිතා කරන්න .
  • $this ස්ථිතික ශ්‍රිත තුළ භාවිතා කළ නොහැක

26

PHP හි, ස්ථිතික ගුණාංග සහ ක්‍රම වෙත ප්‍රවේශ වීම සඳහා ඔබ ස්වයං පදය භාවිතා කරයි.

ප්රශ්නය ඔබ වෙනුවට හැකි බව ය $this->method()සමඟ self::method()නොතකා නම්, ඕනෑම තැනක method()කියන්නේ ස්ථිතික ප්රකාශ හෝ නැත. ඉතින් ඔබ භාවිතා කළ යුත්තේ කුමක්ද?

මෙම කේතය සලකා බලන්න:

class ParentClass {
    function test() {
        self::who();    // will output 'parent'
        $this->who();   // will output 'child'
    }

    function who() {
        echo 'parent';
    }
}

class ChildClass extends ParentClass {
    function who() {
        echo 'child';
    }
}

$obj = new ChildClass();
$obj->test();

මෙම උදාහරණයේ දී, self::who()සෑම විටම 'මාපිය' ප්‍රතිදානය $this->who()කරනු ඇති අතර වස්තුව ඇති පන්තිය මත රඳා පවතී.

දැන් අපි ස්වයං එය නම් වූ පන්ති ගැන බව දකින්න පුළුවන් අතර, $thisයන්නෙන් අදහස් වන්නේ වත්මන් වස්තුවක පන්තියේ .

එබැවින්, ඔබ ස්වයං භාවිතා කළ යුත්තේ $thisලබා ගත නොහැකි වූ විට හෝ වත්මන් ක්‍රමය නැවත ලිවීමට පැවත එන පංතිවලට ඉඩ දීමට ඔබට අවශ්‍ය නැති විට පමණි .


22

පන්ති අර්ථ දැක්වීමක් ඇතුළත, $thisවත්මන් වස්තුවට selfයොමු වන අතර වත්මන් පන්තියට යොමු වේ.

භාවිතා කරමින් පන්ති අංගයක් වෙත යොමු කිරීම අවශ්‍ය වන අතර self, භාවිතා කරන වස්තු මූලද්‍රව්‍යයක් වෙත යොමු වන්න $this.

self::STAT // refer to a constant value
self::$stat // static variable
$this->stat // refer to an object variable  

21

ස්ථිතික නොවන සහ ස්ථිතික සාමාජික විචල්‍යයන් සඳහා $ මෙය සහ ස්වයං නිවැරදි භාවිතය පිළිබඳ උදාහරණයක් මෙන්න:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo $this->non_static_member . ' '
           . self::$static_member;
    }
}

new X();
?> 

21

Http://www.php.net/manual/en/language.oop5.static.php ට අනුව නැත $self. එහි පමණක් $thisපන්ති ස්ථිතික සාමාජිකයන් වෙත යොමු කිරීමට භාවිතා කළ හැකි, පන්ති (වස්තුව) වත්මන් උදාහරණයක් වශයෙන්, සහ ස්වයං, සඳහන් කිරීම සඳහා. වස්තු නිදසුනක් සහ පන්තියක් අතර වෙනස මෙහි ක්‍රියාත්මක වේ.


9
යෝජනාව: ඇසිඩ් ගසන විට මෙම පිළිතුර කියවන්න.
a20

16

මම විශ්වාස කරන්නේ ප්‍රශ්නය ඔබට පන්තියේ ස්ථිතික සාමාජිකයාට ඇමතුමක් ලබා දිය හැකිද යන්නයි ClassName::staticMember. ප්‍රශ්නය වූයේ භාවිතා කිරීම self::classmemberසහ අතර ඇති වෙනස කුමක්ද යන්නයි $this->classmember.

උදා: ඔබ භාවිතා යන්න කිසිදු දෝෂයක් නොමැති පහත සඳහන් උදාහරණ වැඩ දෙකම සඳහා self::හෝ$this->

class Person{
    private $name;
    private $address;

    public function __construct($new_name,$new_address){
        $this->name = $new_name;
        $this->address = $new_address;
    }
}

class Person{
    private $name;
    private $address;
    public function __construct($new_name,$new_address){
        self::$name = $new_name;
        self::$address = $new_address;
    }
}

ඔබේ පිළිතුර "පංතියේ ස්ථිතික සාමාජිකයාට ClassName :: staticMember ඇමතීමෙන් ඔබට ඇමතිය හැකිද යන්න ප්‍රශ්නයක් නොවන බව මම විශ්වාස කරමි. ස්වයං :: පන්තියේ සහ $ මෙම-> පන්තියේ සාමාජිකයා භාවිතා කිරීම අතර ඇති වෙනස කුමක්ද?" ඉන්පසු ඔබ කිසිදු වෙනසක් නොපෙන්වයි. ඇත්ත වශයෙන්ම, විකල්ප දෙක එක හා සමානව ක්‍රියාත්මක වන ස්ථානයක් ඔබ පෙන්වයි. -1
බට්ල් බට්කස්

එසේ වුවද ප්‍රයෝජනවත්. විෂය පථය විසර්ජනය පිළිබඳ වූ අතර මෙම කොටස php අත්පොතෙහි පැහැදිලි නැත. මම තවමත් එය ප්‍රයෝජනවත් යැයි
සිතමි

2
Fatal error: Access to undeclared static property: Person::$name in D:\LAMP\www\test.php on line 16
කේ-තුවක්කු

16

self වත්මන් පන්තිය (එය හැඳින්වෙන),

$thisවත්මන් වස්තුව යොමු කරයි. ඔබට ස්වයං වෙනුවට ස්ථිතික භාවිතා කළ හැකිය. උදාහරණය බලන්න:

    class ParentClass {
            function test() {
                    self::which();  // output 'parent'
                    $this->which(); // output 'child'
            }

            function which() {
                    echo 'parent';
            }
    }

    class ChildClass extends ParentClass {
            function which() {
                    echo 'child';
            }
    }

    $obj = new ChildClass();
    $obj->test();

ප්‍රතිදානය: මව් දරුවා


16
  • වස්තු දර්ශකය $thisවත්මන් වස්තුවට යොමු වේ.
  • පන්ති අගය staticවත්මන් වස්තුවට යොමු වේ.
  • පංති අගය selfයනු එය අර්ථ දක්වා ඇති නිශ්චිත පන්තියට ය.
  • පංති අගය parentයන්නෙන් එය අර්ථ දක්වා ඇති නිශ්චිත පන්තියේ මවුපියන්ට යොමු වේ.

අධි බර පැටවීම පෙන්වන පහත උදාහරණය බලන්න.

<?php

class A {

    public static function newStaticClass()
    {
        return new static;
    }

    public static function newSelfClass()
    {
        return new self;
    }

    public function newThisClass()
    {
        return new $this;
    }
}

class B extends A
{
    public function newParentClass()
    {
        return new parent;
    }
}


$b = new B;

var_dump($b::newStaticClass()); // B
var_dump($b::newSelfClass()); // A because self belongs to "A"
var_dump($b->newThisClass()); // B
var_dump($b->newParentClass()); // A


class C extends B
{
    public static function newSelfClass()
    {
        return new self;
    }
}


$c = new C;

var_dump($c::newStaticClass()); // C
var_dump($c::newSelfClass()); // C because self now points to "C" class
var_dump($c->newThisClass()); // C
var_dump($b->newParentClass()); // A because parent was defined *way back* in class "B"

බොහෝ විට ඔබ භාවිතා ඇයි වන වත්මන් පන්ති වෙත යොමු කිරීමට අවශ්ය staticහෝ $this. කෙසේ වෙතත්, ඔබට අවශ්‍ය වන අවස්ථා තිබේ, self මන්ද එය මුල් පන්තිය දිගු කරන්නේ කුමක් වුවත් ඔබට අවශ්‍ය නිසාය. (ඉතා කලාතුරකින්)


14

මෙහි කිසිවෙකු රංගනයන් ගැන කතා නොකළ බැවින්, මා කළ කුඩා මිණුම් ලකුණක් මෙහි ඇත (5.6):

 Name     | Time    | Percent  
----------|---------|---------  
 $this->  | 0.99163 | 106.23%  
 self::   | 0.96912 | 103.82%  
 static:: | 0.93348 | 100%

ඒවා ලකුණු 2 000 000 ක් සඳහා වන ප්‍රති results ල වන අතර මම භාවිතා කළ කේතය මෙන්න:

<?php

require '../vendor/autoload.php';

// My small class to do benchmarks
// All it does is looping over every test x times and record the
//   time it takes using `microtime(true)`
// Then, the percentage is calculated, with 100% being the quickest
// Times are being rouned for outputting only, not to calculate the percentages
$b = new Tleb\Benchmark\Benchmark(2000000);

class Foo
{
    public function calling_this()
    {
        $this->called();
    }

    public function calling_self()
    {
        self::called();
    }

    public function calling_static()
    {
        static::called();
    }

    public static function called()
    {
    }
}

$b->add('$this->',  function () { $foo = new Foo; $foo->calling_this(); });
$b->add('self::',   function () { $foo = new Foo; $foo->calling_self(); });
$b->add('static::', function () { $foo = new Foo; $foo->calling_static(); });

$b->run();

1
විවෘත නොවන ශ්‍රිතයක් 2 000 000 වාරයක් ඇමතීම 1s පවතී. පීඑච්පී වලට ආදරෙයි.
rr-

හොඳ පැරණි PHP. :) නමුත් ඇමතුමක් = 0.001ms. එය එතරම් නරකද?
tleb කරන්න

මම විශ්වාස කරන්නේ මෙය (හා ඒ හා සමාන දේ) ඔබ දේවල් හැඹිලි නොකළහොත් ORM වැනි දේවල් මන්දගාමී වන්නේ මන්ද යන්නයි, සහ ස්ථිතික අඩවි උත්පාදක යන්ත්රය යනු දෙයක්.
rr-

2
එය න්‍යායාත්මකව 1 ප්‍රොසෙසර ඔරලෝසු චක්‍රයක් ගත යුතු අතර එය 1 / 2e9 s = 0.5 nsමේ දිනවල සිදු වේ
Buddy

මගේ පිළිතුර නැවත කියවන්න. ප්‍රවේශම් වන්න: එය පන්තියනිර්මාණය කරයි . මම usetbh යතුර භාවිතා නොකළේ මන්දැයි මම නොදනිමි, නමුත් මිණුම් ලකුණක් නැවත කිරීමට මට තවදුරටත් PHP නොමැත, එය නැවත ස්ථාපනය කිරීමට මට දැනෙන්නේ නැත.
tleb

13

විට selfසමග භාවිතා වන ::එය ස්ථිතික සහ-ස්ථිතික නොවන සන්දර්භයන් තුළ දෙකම සිදු කළ හැකි වත්මන් පන්ති, අදහස් ක්රියාකරු. $thisවස්තුවටම යොමු වේ. ඊට අමතරව, $thisස්ථිතික ක්‍රම ඇමතීමට භාවිතා කිරීම සම්පූර්ණයෙන්ම නීතිමය ය (නමුත් ක්ෂේත්‍ර වෙත යොමු නොවේ).


9

මම එකම ප්‍රශ්නයකට දිව ගිය අතර සරල පිළිතුර නම්:

  • $this පන්තියේ උදාහරණයක් අවශ්‍යයි
  • self:: නැහැ

ඔබ ස්ථිතික ක්‍රම හෝ ස්ථිතික ගුණාංග භාවිතා කරන විට සහ පන්තියේ වස්තුවක් නොමැතිව ඒවා ඇමතීමට අවශ්‍ය සෑම විටම ඔබ ඒවා self:ඇමතීමට භාවිතා කළ යුතුය, මන්ද $thisසෑම විටම වස්තුවක් නිර්මාණය කිරීම අවශ්‍ය වේ.


7

$thisවත්මන් පන්ති වස්තුවට selfයොමු වේ, වත්මන් පන්තියට (වස්තුව නොවේ). පංතිය යනු වස්තුවේ සැලැස්මයි. එබැවින් ඔබ පන්තියක් අර්ථ දක්වයි, නමුත් ඔබ වස්තු සාදයි.

එබැවින් වෙනත් වචන වලින් කිවහොත්, භාවිතා කරන්න self for staticසහthis for none-static members or methods .

ළමා / මාපිය අවස්ථා වලදී self / parentබොහෝ විට භාවිතා කරනුයේ හඳුනාගත් ළමා හා මව් පන්තියේ සාමාජිකයින් සහ ක්‍රම සඳහා ය.


7

මීට අමතරව $this::තවමත් සාකච්ඡා කර නොමැත.

තොරතුරු දැනගැනීමේ අරමුණු සඳහා පමණක්, වර්තමාන විෂය පථයේ අගය ලබා ගැනීම සඳහා ක්ෂණික වස්තූන් සමඟ ගනුදෙනු කිරීමේදී PHP 5.3 වන විට, භාවිතයට වඩා වෙනස්ව static::, කෙනෙකුට විකල්පයක් ලෙස භාවිතා කළ හැකිය $this::.

http://ideone.com/7etRHy

class Foo
{
    const NAME = 'Foo';

    //Always Foo::NAME (Foo) due to self
    protected static $staticName = self::NAME;

    public function __construct()
    {
        echo $this::NAME;
    }

    public function getStaticName()
    {
       echo $this::$staticName;
    }
}

class Bar extends Foo
{
    const NAME = 'FooBar';

    /**
     * override getStaticName to output Bar::NAME
     */
    public function getStaticName()
    {
        $this::$staticName = $this::NAME;
        parent::getStaticName();
    }
}

$foo = new Foo; //outputs Foo
$bar = new Bar; //outputs FooBar
$foo->getStaticName(); //outputs Foo
$bar->getStaticName(); //outputs FooBar
$foo->getStaticName(); //outputs FooBar

ඉහත කේතය භාවිතා කිරීම සාමාන්‍ය හෝ නිර්දේශිත භාවිතයක් නොවේ, නමුත් එය හුදෙක් එහි භාවිතය නිදර්ශනය කිරීම සඳහා වන අතර එය "ඔබ දැන සිටියාද?" මුල් පෝස්ටරයේ ප්‍රශ්නයට අදාළව.

එය ප්‍රතිවිරුද්ධ ලෙස $object::CONSTANTඋදාහරණයක් echo $foo::NAME;ලෙස භාවිතා කිරීම ද නිරූපණය කරයි$this::NAME;


5

selfඑම පන්තියේ වස්තුවක් / නිදසුනක් නිර්මාණය නොකර ඔබට පන්තියේ ක්‍රමයක් ඇමතීමට අවශ්‍ය නම් භාවිතා කරන්න , එමඟින් RAM ඉතිරි වේ (සමහර විට ඒ සඳහා ස්වයං භාවිතා කරන්න). වෙනත් වචන වලින් කිවහොත්, එය ඇත්ත වශයෙන්ම ක්‍රමවේදයක් සංඛ්‍යාත්මකව කැඳවයි. thisවස්තු ඉදිරිදර්ශනය සඳහා භාවිතා කරන්න .


2

1 වන අවස්ථාව: selfපන්ති නියතයන් සඳහා භාවිතය භාවිතා කළ හැකිය

 class classA { 
     const FIXED_NUMBER = 4; 
     ස්වයං :: POUNDS_TO_KILOGRAMS
}

ඔබට එය පන්තියෙන් පිටත ඇමතීමට අවශ්‍ය නම්, නියතයන්ට classA::POUNDS_TO_KILOGRAMSප්‍රවේශ වීමට භාවිතා කරන්න

2 වන අවස්ථාව: ස්ථිතික ගුණාංග සඳහා

class classC {
     පොදු කාර්යය __construct () { 
     self :: counter _ counter ++; $ this-> num = self :: counter _ counter;
   }
}

1

Php.net අනුව මෙම සන්දර්භය තුළ විශේෂ ප්රධාන වචන තුනක් ඇත: self, parentසහ static. පංති අර්ථ දැක්වීම ඇතුළත සිට ගුණාංග හෝ ක්‍රම වෙත ප්‍රවේශ වීමට ඒවා භාවිතා වේ.

$this, අනෙක් අතට, එම පන්තියට ප්‍රවේශ විය හැකි තාක් ඕනෑම පන්තියක නිදසුනක් සහ ක්‍රමවේදයක් හැඳින්වීමට භාවිතා කරයි.


-1

self ::  keyword වත්මන් පන්තිය සඳහා භාවිතා කරන අතර මූලික වශයෙන් එය ස්ථිතික සාමාජිකයන්, ක්‍රම සහ නියතයන් වෙත ප්‍රවේශ වීමට භාවිතා කරයි. එහෙත්, නඩුව $ මේ ඔබ ස්ථිතික සාමාජික, ක්රමය හා කාර්යයන් ඇමතිය හැකි නොවේ.

ඔබට වෙනත් පන්තියක ස්වයං :: මූල පදය භාවිතා කළ හැකි අතර ස්ථිතික සාමාජිකයන්, ක්‍රමවේදය සහ නියතයන් වෙත ප්‍රවේශ විය හැකිය. එය මව් පංතියෙන් විහිදෙන විට සහ keyword මෙම මූල පදය සම්බන්ධයෙන්. මව් පංතියෙන් විහිදෙන විට ස්ථිතික නොවන සාමාජිකයින්ට, ක්‍රමයකට සහ වෙනත් පන්තියකට ප්‍රවේශ විය හැකිය.

පහත දැක්වෙන කේතය ස්වයං :: සහ key මෙම මූල පදය සඳහා උදාහරණයකි . ඔබේ කේත ගොනුවේ කේතය පිටපත් කර අලවන්න සහ ප්‍රතිදානය බලන්න.

class cars{
    var $doors=4;   
    static $car_wheel=4;

  public function car_features(){
    echo $this->doors." Doors <br>";
    echo self::$car_wheel." Wheels <br>"; 
  }
}

class spec extends cars{
    function car_spec(){
        print(self::$car_wheel." Doors <br>");
        print($this->doors." Wheels <br>");
    }
}

/********Parent class output*********/

$car = new cars;
print_r($car->car_features());

echo "------------------------<br>";

/********Extend class from another class output**********/


$car_spec_show=new spec;

print($car_spec_show->car_spec());
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.