PHP bir nesne, örnek kimliği alın

8 Cevap php

Ben StackOverflow bir süre önce öğrenmek ettik we can get the "instance ID" of any resource, örneğin:

var_dump(intval(curl_init()));  // int(2)
var_dump(intval(finfo_open())); // int(3)
var_dump(intval(curl_init()));  // int(4)
var_dump(intval(finfo_open())); // int(5)
var_dump(intval(curl_init()));  // int(6)

Ben sınıflarına benzer ancak uygulanan bir şey gerekir:

class foo {
    public function __construct() {
        ob_start();
        var_dump($this); // object(foo)#INSTANCE_ID (0) { }
        echo preg_replace('~.+#(\d+).+~s', '$1', ob_get_clean());
    }
}

$foo = new foo();  // 1
$foo2 = new foo(); // 2

Yukarıdaki çalışıyor ama ben, en azından çıkış tamponları dahil etmedi birini daha hızlı bir çözüm için umut oldu ya da. Bu mutlaka yapıcısı içinde hatta sınıfın kendisi içinde kullanılan olmayacağını unutmayın!

spl_object_hash() I identical sağlamalarının iki nesne üretmek için arıyorum ne değildir:

var_dump(spl_object_hash($foo));  // 000000005111e639000000003a87b42e
var_dump(spl_object_hash($foo2)); // 000000005111e639000000003a87b42e

Kaynakları gibi int Döküm nesneleri ile çalışmak için görünmüyor:

Class foo Notice: Nesne int dönüştürülür olamazdı.

Is there a quick way to grab the same output without using object properties?


Ayrıca var_dump(), I debug_zval_dump() da, nesne örneğini verir bunun sonucu dönmek olmadığından ne yazık ki o da çıktı tamponlama ihtiyacı olduğunu deneme yanılma yoluyla keşfettik.

To the down voters: Bu temel bir sorudur düşünüyorsanız, bir çözüm önermek, nedenleri açıklamak ya.

8 Cevap

Evet, evet, bir uzantısı olan.

Yok, arada, olan nesneler için kullanılan kolları, yeniden kullanılabilir olduğunu unutmayın.

phpize && ./configure && make && make install ile inşa

testext.h

#ifndef PHP_EXTTEST_H
# define PHP_EXTTEST_H
# ifdef HAVE_CONFIG_H
#  include<config.h>
# endif
# include <php.h>
extern zend_module_entry testext_module_entry;
#define phpext_testext_ptr &testext_module_entry
#endif

testext.c

#include "testext.h"

PHP_FUNCTION(get_object_id)
{
    zval *obj;
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj)
            == FAILURE) {
        return;
    }

    RETURN_LONG(Z_OBJ_HANDLE_P(obj));
}

static zend_function_entry ext_functions[] = {
    PHP_FE(get_object_id, NULL)
    {NULL, NULL, NULL, 0, 0}
};

zend_module_entry testext_module_entry = {
    STANDARD_MODULE_HEADER,
    "testext",
    ext_functions, /* Functions */
    NULL, /* MINIT */
    NULL, /* MSHUTDOWN */
    NULL, /* RINIT */
    NULL, /* RSHUTDOWN */
    NULL, /* MINFO */
    NO_VERSION_YET,
    STANDARD_MODULE_PROPERTIES
};

ZEND_GET_MODULE(testext)

config.m4

PHP_ARG_ENABLE(testext,
  [Whether to enable the "testext" extension],
  [  enable-testext         Enable "testext" extension support])

if test $PHP_EXTTEST != "no"; then
  PHP_SUBST(EXTTEST_SHARED_LIBADD)
  PHP_NEW_EXTENSION(testext, testext.c, $ext_shared)
fi

Test script

<?php
$a = new stdclass();
$b = new stdclass();
var_dump(get_object_id($a));
var_dump(get_object_id($b));

Output

int(1)
int(2)

Eğer yapmak için çalışıyoruz ne, Aspect-Oriented Programming (AOP) aslında.

Bu noktada PHP AOP için mevcut çerçeveler en az bir çift vardır:

  • seasar (eski PHPaspect) Eclipse ile entegre bir büyük çerçeve - ekran resmi bir proje boyunca belirli bir yeni deyimi etrafında bazı kod dokuma, sizin sorunuzu yanıtlayan küçük bir kod parçası da gösterir.
  • php-aop AOP için hafif bir çerçevedir.
  • typo3 yerleşik bir AOP çerçevesi vardır

Bu gereksinimizin olabilir, ancak bu gibi fikirlerin arkasında düşünme tür keşfetmek RabbitHole aşağı götürecek bulmak ve size genel olarak yazılım geliştirme konusunda düşünmek için yeni yollar öğretmek olabilir - AOP size izin, güçlü bir kavram stratejileri ve endişeleri, ya da "yönleri" açısından programlamak için.

PHP gibi diller programming görevleri çözmek için tasarlanmıştır - APO kavramı a programmer's görevleri çözmek için tasarlanmıştır. Belirli bir endişe kod temeli her zaman yerine getirmiş olur sağlamak için nasıl düşünmek gerekir normalde, doğrudan bu şartlar altında bunu uygulamak, programlama yaparken nasıl bu kadar basitçe bir "yönü" düşünmek ve güvenebilirsiniz Lütfen endişeler her zaman uygulanacak üzerinde.

Daha az disiplin gerektirir ve pratik programlama görevleri çözme yerine üst düzey yapısal kod gereksinimleri ile mimar için yol çalışırken odaklanabilirsiniz.

Neyse, zaman 5 dakika değer olabilir ;-)

İyi şanslar!

Alix, soru çözüm tam olarak ne ihtiyaç vardı, ama aslında bir nesne bir nesne varken, tatili var_dump son # döndürür. Ben, bu sabit hızlı regex yapılmış ve bir güzel küçük fonksiyonun içine koyun.

/**
 * Get global object ID
 * From: http://stackoverflow.com/questions/2872366/get-instance-id-of-an-object-in-php
 * By: Alix Axel, non-greedy fix by Nate Ferrero
 */
function get_object_id(&$obj) {
    if(!is_object($obj))
        return false;
    ob_start();
    var_dump($obj);// object(foo)#INSTANCE_ID (0) { }
    preg_match('~^.+?#(\d+)~s', ob_get_clean(), $oid);
    return $oid[1]; 
}

Ben PECL runkit bu test etkin zorunda değilsiniz, ama bu sınıfın bir örneği oluşturulduktan sonra ilk kez sınıf tanımından yapıcı kodunu kaldırmak için izin verebilir.

Eğer yapıcısı içinde kurucu kaldırabilirsiniz olsun ilginç bir deneme olacak.

Çıktı tamponlama kullanmak istemiyorsanız ... belki kullanmak var_export instead of var_dump?

Sürece taban sınıf size bu ihtiyacınız olacak tüm sınıfları uygulamak gibi, böyle bir şey yapabilirsiniz:

class MyBase
{
    protected static $instances = 0;
    private $_instanceId  = null;
    public function getInstanceId()
    {
        return $this->_instanceId;
    }

    public function __construct()
    {
        $this->_instanceId = ++self::$instances;
    }
}

class MyTest extends MyBase
{
    public function Foo()
    {
        /* do something really nifty */
    }
}

$a = new MyBase();
$b = new MyBase();

$c = new MyTest();
$d = new MyTest();


printf("%d (should be 1) \n", $a->getInstanceId());
printf("%d (should be 2) \n", $b->getInstanceId());
printf("%d (should be 3) \n", $c->getInstanceId());
printf("%d (should be 4) \n", $d->getInstanceId());

Çıktı olacaktır:

1 (should be 1) 
2 (should be 2) 
3 (should be 3) 
4 (should be 4)