ทำไม PHP ไม่รองรับฟังก์ชั่นการโหลดมากเกินไป?


37

ฉันสงสัยว่าหนึ่งในคุณสมบัติที่สำคัญของภาษาการเขียนโปรแกรมคือการมีความสามารถในการโอเวอร์โหลดฟังก์ชั่นผ่านข้อโต้แย้ง ฉันคิดว่ามันเป็นสิ่งสำคัญในบริบทของการเขียนโปรแกรมเชิงวัตถุ

มันตั้งใจทิ้งไว้และไม่ได้รับอนุญาต? หรือการบรรทุกเกินพิกัดไม่ใช่การปฏิบัติที่ดี?


27
การโอเวอร์โหลดฟังก์ชั่นไม่ใช่คุณสมบัติของการเขียนโปรแกรม OO จริงๆ ฟังก์ชั่น Sub-class over-ridingสำหรับวัตถุประสงค์ของ polymorphism นั้นมักจะถือว่าเป็นคุณสมบัติที่จำเป็นของ OO - แต่ไม่ใช่ฟังก์ชั่นการบรรทุกเกินพิกัดตามข้อโต้แย้ง Python ไม่มีฟังก์ชั่นอิงตามอาร์กิวเมนต์มากไป อย่างไรก็ตามการใช้งานมากเกินไปอาจเป็นประโยชน์ในภาษาที่พิมพ์แบบคงที่ซึ่งการเชื่อมฟังก์ชันจะเกิดขึ้นในเวลารวบรวมและขึ้นอยู่กับประเภทของพารามิเตอร์ฟังก์ชันแต่ละตัว
ชาร์ลส์ซัลเวี

2
@ CharlesSalvia นั่นจะเป็นคำตอบที่ดี
kiamlaluno

1
เขาพูดอะไร. นอกจากนี้ฟังก์ชั่นการบรรทุกเกินพิกัดเป็น overrated คุณไม่จำเป็นต้องใช้ชื่อฟังก์ชั่นเดียวกันสำหรับฟังก์ชั่นที่แตกต่างกัน เพียงแค่ให้ชื่อฟังก์ชั่นของคุณที่คล้ายกัน แต่ไม่เหมือนกัน ผู้ประกอบการมากไปในทางตรงกันข้าม ...
นาย Lister

แม้ว่าจะไม่ใช่คำตอบสำหรับคำถามเฉพาะ แต่ฉันจะโพสต์ลิงก์นี้ซึ่งทำให้ฉันเข้าใจวิธีใช้การโอเวอร์โหลดใน PHP ได้ดีขึ้น หวังว่าจะช่วยได้
DiegoDD

คำตอบ:


33

ใครบอกว่า PHP ไม่รองรับฟังก์ชั่นการโหลดมากเกินไป? !!!

ที่จริงแล้ว PHP รองรับฟังก์ชั่นการทำงานหนักเกินไป แต่ก็แตกต่างกัน ฟีเจอร์การโอเวอร์โหลดของ PHP แตกต่างจากของ Java:

การตีความ "overloading" ของ PHP นั้นแตกต่างจากภาษาเชิงวัตถุส่วนใหญ่ การโอเวอร์โหลดแบบดั้งเดิมให้ความสามารถในการมีหลายวิธีที่มีชื่อเดียวกัน แต่มีปริมาณและประเภทของอาร์กิวเมนต์ที่แตกต่างกัน

ชำระเงินบล็อกรหัสต่อไปนี้

ฟังก์ชั่นเพื่อค้นหาผลรวมของตัวเลข n:

function findSum() {
    $sum = 0;
    foreach (func_get_args() as $arg) {
        $sum += $arg;
    }
    return $sum;
}

echo findSum(1, 2), '<br />'; //outputs 3
echo findSum(10, 2, 100), '<br />'; //outputs 112
echo findSum(10, 22, 0.5, 0.75, 12.50), '<br />'; //outputs 45.75

ฟังก์ชั่นเพื่อเพิ่มตัวเลขสองตัวหรือเพื่อเชื่อมสองสายเข้าด้วยกัน:

function add() {
    //cross check for exactly two parameters passed
    //while calling this function
    if (func_num_args() != 2) {
        trigger_error('Expecting two arguments', E_USER_ERROR);
    }

    //getting two arguments
    $args = func_get_args();
    $arg1 = $args[0];
    $arg2 = $args[1];

    //check whether they are integers
    if (is_int($arg1) && is_int($arg2)) {
        //return sum of two numbers
        return $arg1 + $arg2;
    }

    //check whether they are strings
    if (is_string($arg1) && is_string($arg2)) {
        //return concatenated string
        return $arg1 . ' ' . $arg2;
    }

    trigger_error('Incorrect parameters passed', E_USER_ERROR);
}

echo add(10, 15), '<br />'; //outputs 25
echo add("Hello", "World"), '<br />'; //outputs Hello World

วิธีการเชิงวัตถุรวมถึงวิธีการมากไป:

การใช้งานมากเกินไปใน PHP นั้นหมายถึงคุณสมบัติและวิธีการ "สร้าง" แบบไดนามิก เอนทิตีแบบไดนามิกเหล่านี้ได้รับการประมวลผลด้วยวิธีเวทย์มนตร์ที่ใคร ๆ ก็สามารถสร้างได้ในคลาสสำหรับประเภทการกระทำต่าง ๆ

Ref: http://php.net/manual/th/language.oop5.overloading.php

ใน PHP การบรรทุกเกินพิกัดหมายความว่าคุณสามารถเพิ่มสมาชิกวัตถุที่ใช้เวลาโดยการใช้บางส่วนของวิธีการมายากลเช่น__set, __get, __callฯลฯ

class Foo {

    public function __call($method, $args) {

        if ($method === 'findSum') {
            echo 'Sum is calculated to ' . $this->_getSum($args);
        } else {
            echo "Called method $method";
        }
    }

    private function _getSum($args) {
        $sum = 0;
        foreach ($args as $arg) {
            $sum += $arg;
        }
        return $sum;
    }

}

$foo = new Foo;
$foo->bar1(); // Called method bar1
$foo->bar2(); // Called method bar2
$foo->findSum(10, 50, 30); //Sum is calculated to 90
$foo->findSum(10.75, 101); //Sum is calculated to 111.75

29
ส่วนที่สองเกี่ยวกับสิ่งที่ PHP เรียกว่า "การบรรทุกเกินพิกัด" ไม่ใช่สิ่งที่คล้ายกันทั้งหมด เป็นเพียง PHP โดยใช้ชื่อที่ยอมรับกันดีสำหรับสิ่งที่แตกต่างกันส่วนใหญ่พิจารณาว่าเป็น PHP มันไม่น่าแปลกใจเลย
phant0m

10
ที่ไม่ได้ทำงานมากไป findSum(10, "steve", { 86, "2012-09-20" });เกินฟังก์ชั่นอย่างแท้จริงตอนนี้เขียนเทียบเท่าของ PHP เกินจริงจะอนุญาตให้พารามิเตอร์ใหม่ประเภทที่แตกต่าง
Joel Etherton

3
@JoelEtherton - การตีความของ "overloading" ของ PHP แตกต่างจากภาษาเชิงวัตถุส่วนใหญ่ การโอเวอร์โหลดแบบดั้งเดิมให้ความสามารถในการมีหลายวิธีที่มีชื่อเดียวกัน แต่มีปริมาณและประเภทของอาร์กิวเมนต์ที่แตกต่างกัน ref: http://php.net/manual/en/language.oop5.overloading.php การ โหลดมากเกินไปใน PHP นั้นหมายถึงคุณสมบัติและวิธีการ "สร้าง" แบบไดนามิก เอนทิตีแบบไดนามิกเหล่านี้ได้รับการประมวลผลด้วยวิธีเวทย์มนตร์ที่ใคร ๆ ก็สามารถสร้างได้ในคลาสสำหรับประเภทการกระทำต่าง ๆ
rajukoyilandy

7
@rajukoyilandy: ทุกอย่างดีและดี แต่คำถามของ OP ถามว่าทำไม PHP ไม่ใช้การโหลดมากเกินไป "ดั้งเดิม" คำตอบของคุณไม่ได้อยู่ที่
Joel Etherton

7
นี่ไม่ใช่การโหลดมากไป ยังมีเพียงหนึ่งคำจำกัดความ / ประกาศของฟังก์ชั่น สิ่งนี้จะเทียบเท่ากับ va_list / va_arg ใน C ++ คุณช่วยแก้ปัญหาเดียวกันได้ไหม? ใช่. แต่มันก็ยังไม่มากไป
ลุค

13

ไม่ได้เป็น "แบบดั้งเดิมมากไป" การสนับสนุนเต็มรูปแบบบางส่วนเท่านั้น

คำจำกัดความ : "การโอเวอร์โหลดแบบดั้งเดิม" ให้เมื่อเรียกวิธีการความสามารถในการมีหลายวิธีที่มีชื่อเดียวกัน แต่ปริมาณที่แตกต่างกันและประเภทของการขัดแย้ง สำหรับการประกาศเมธอดมันมีตัวเลือกในการแสดงการประกาศแยก / แยกสำหรับแต่ละฟังก์ชั่นที่โอเวอร์โหลด

หมายเหตุ: ส่วนที่สองของคำนิยามนี้มักจะเกี่ยวข้องกับภาษาการเขียนโปรแกรมแบบคงที่ซึ่งจะทำการตรวจสอบประเภทและ / หรือการตรวจสอบ arityเพื่อเลือกการประกาศที่ถูกต้อง PHP ไม่ได้เป็นภาษาแบบคงที่พิมพ์มันเป็นแบบไดนามิกและการใช้พิมพ์ที่อ่อนแอ


สนับสนุน PHP :

  • ใช่ความสามารถในการเรียกหลายวิธีที่มีชื่อเดียวกัน แต่ปริมาณที่แตกต่างกัน ดูfunc_get_argsและคำตอบ @rajukoyilandy เราสามารถใช้และf(x)f(x,y)

  • ใช่ความสามารถในการเรียกหลายวิธีที่มีชื่อเดียวกัน แต่ประเภทที่แตกต่างกัน ใช้ gettypeภายในวิธีการภายใน

    • แต่สำหรับการอ้างอิง ... มีเพียงตัวแปรเท่านั้นที่สามารถส่งผ่านโดยการอ้างอิงคุณไม่สามารถจัดการการโอเวอร์โหลดสำหรับการตรวจจับค่าคงที่ / ตัวแปร
  • ไม่ให้ความสามารถในการประกาศหลายวิธีที่มีชื่อเดียวกัน แต่ปริมาณที่แตกต่างกัน นี่เป็นเพราะเราสามารถโทรf(x)และf(x,y)ด้วยการfประกาศเดียวกัน

  • ไม่ให้ความสามารถในการประกาศหลายวิธีที่มีชื่อเดียวกัน แต่ประเภทที่แตกต่างกัน เพราะนี่คือ PHP คอมไพเลอร์จะต้องตีความว่าเป็นฟังก์ชั่นเดียวกันกับที่f($integer,$string) f($string,$integer)

ดูที่เอกสารอธิบายการโหลดเกิน PHP5สำหรับคำอธิบายของ "คำอธิบายการโอเวอร์โหลดที่ไม่ใช่แบบดั้งเดิม"

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.