Có cách nào để định nghĩa một lớp để nó mở rộng một lớp khác chỉ khi lớp kia có sẵn không?Lớp động mở rộng
Trả lời
Có gì mà sẽ cho phép bạn làm
class Foo extendsIfExist Bar
Nhưng bạn có thể monkeypatch Foo với runkit 's
Ví dụ từ PHP Manual:
class myParent {
function parentFunc() {
echo "Parent Function Output\n";
}
}
class myChild {
}
runkit_class_adopt('myChild','myParent');
myChild::parentFunc();
Tiện ích mở rộng runkit có sẵn từ PECL. Tuy nhiên, việc sử dụng nó không được khuyến khích vì cần nó hầu như luôn là chỉ báo cho một thiết kế thiếu sót.
Tuyên bố từ chối trách nhiệm: Tôi chỉ giả định một ví dụ như ví dụ sau là lý do bạn đặt câu hỏi. Bỏ qua phần đó của câu trả lời nếu không.
Nếu bạn cần một số chức năng nhất định có điều kiện trong thời gian chạy, hãy xem xét tổng hợp lớp bạn muốn mở rộng, ví dụ: hãy thử điều gì đó dọc theo các dòng của
interface Loggable
{
public function log($message);
}
class Foo implements Loggable
{
protected $logger;
public function setLogger($logger)
{
$this->logger = $logger;
}
public function log($message)
{
if($this->logger !== NULL) {
return $this->logger->log($message);
}
}
}
Trong ví dụ trên, chức năng chúng tôi muốn là log()
. Vì vậy, thay vì phát hiện nếu một lớp logger có sẵn và sau đó monkeypatching chức năng này vào lớp Foo của chúng tôi, chúng tôi yêu cầu nó yêu cầu chức năng này bằng cách thêm một giao diện Loggable. Nếu tồn tại một lớp Logger, chúng ta khởi tạo và tổng hợp nó trong Foo. Nếu nó không tồn tại, chúng ta vẫn có thể gọi nhật ký nhưng nó sẽ không làm gì cả. Đây là nhiều hơn nữa solid.
Giải pháp để cung cấp "mở rộng nếu tồn tại" mà không sử dụng eval: http://stackoverflow.com/a/9898049/441739 –
Ý của bạn là gì?
<?php
class Foo{
}
if(class_exists('Foo')){
class SubFoo extends Foo{
}
}
if(class_exists('Bar')){
class SubBar extends Bar{
}
}
$a = new SubFoo; // OK
$b = new SubBar; // Fatal error: Class 'SubBar' not found
Không hay, nhưng tốt hơn so với phương pháp 'eval()'! –
Đây là câu trả lời và phần mở rộng cho câu trả lời của Pekka.
Thứ nhất tại Pekka, tôi nghĩ rằng các eval là hoàn toàn sai, những gì là sai với
if(class_exists("bar"))
{
class foo extends bar
{
}
}
đó cũng là câu trả lời là tốt của tôi.
gặp một yêu cầu tương tự gần đây, nơi một lớp trong thư viện của tôi cần để tự động mở rộng từ ClassB (nếu có), nếu không mở rộng từ lớp A.
Giải pháp của tôi (mã của tôi là namespaced, cùng khái niệm áp dụng không phân biệt) :
namespace someNamespace;
spl_autoload_register(function($class) {
if (strcasecmp($class, 'someNamespace\SomeFakeClass') === 0) {
if (class_exists('ClassB',false)) {
class_alias('ClassB', 'someNamespace\SomeFakeClass');
} else {
class_alias('ClassA', 'someNamespace\SomeFakeClass');
}
}
}, true, true);
/** @noinspection PhpUndefinedClassInspection */
/** @noinspection PhpUndefinedNamespaceInspection */
class MyClass extends \someNamespace\SomeFakeClass {
# ... real logic here ...
}
Sử dụng giải pháp trên, lớp MyClass sẽ tự động kế thừa từ ClassB nếu tồn tại, nếu không nó được thừa hưởng từ ClassA.
Giải pháp này tránh sử dụng eval, đây là một lợi thế lớn đối với tôi.
Hy vọng điều này sẽ hữu ích.
CHỈNH SỬA: Chỉ cần lưu ý, ký hiệu @noinspection tồn tại để các IDE chẳng hạn như PHPStorm sẽ không báo cáo lỗi liên quan đến lớp không tồn tại.
Tôi đã thực hiện theo cách này.
if (class_exists('parentClass') {
class _myClass extends parentClass {}
} else {
class _myClass {}
}
class myClass extends _myClass
{
...
}
Lỗi nếu tệp ở bên ngoài 'Lỗi nghiêm trọng: Khai báo lớp có thể không được lồng nhau' –
- 1. Mở rộng lớp học cho hoạt động
- 2. Javascript mở rộng lớp
- 3. Mở rộng nhiều lớp
- 4. Cách mở rộng lớp css
- 5. PHP - mở rộng phương pháp như mở rộng một lớp
- 6. phương pháp mở rộng để mở rộng lớp tĩnh
- 7. startService từ lớp không mở rộng Hoạt động
- 8. Mở rộng Groovy lớp String
- 9. Lớp mở rộng là gì?
- 10. lớp bên trong mở rộng
- 11. Cách mở rộng các lớp học bootstrap
- 12. CSS-Less lớp mở rộng lớp với lớp giả
- 13. Mở rộng FragmentActivity thay vì Hoạt động
- 14. PHP-OOP mở rộng hai lớp?
- 15. Danh sách động tự động mở rộng
- 16. Javadoc khi mở rộng lớp chung với lớp phi generic
- 17. C#: Mở rộng từ hơn 1 lớp
- 18. get mẹ mở rộng lớp trong php
- 19. khai báo proporder trên lớp mở rộng
- 20. CSS - Mở rộng thuộc tính lớp học
- 21. lấy tên tệp của lớp mở rộng
- 22. Kỳ lạ PHP mở rộng lớp IMagick
- 23. Phương pháp mở rộng trên lớp tĩnh?
- 24. Mở rộng Lớp tuyên bố PDO
- 25. ViewBag return null trong Lớp mở rộng
- 26. Java: Mở rộng lớp lúc chạy
- 27. Mở rộng các lớp nội trang SWIG
- 28. Mở rộng lớp Java với Scala Trait
- 29. Mở rộng các lớp tĩnh PHP
- 30. Mở rộng enum trong các lớp thừa
Điều này không có ý nghĩa nhiều từ quan điểm kiến trúc - bạn cần mở rộng lớp học hoặc bạn không cần. Bạn đang cố gắng đạt được điều gì? (Có thể có một cách dễ dàng hơn.) –
Không có lý do gì để tự động tạo các lớp, bạn nên có một hệ thống vững chắc không bao giờ nên yêu cầu một thứ như vậy. trừ khi được nêu ở trên, có thể có cách tiếp cận đơn giản hơn cho mục tiêu của bạn. – RobertPitt
RobertPitt chính xác 100%. Tôi sẽ suy nghĩ lại vấn đề bởi vì nó có vẻ như có một lỗi lớn hơn trong cấu trúc cần được xem xét đầu tiên. –