Como obtenho o nome de classe não qualificado (curto) de um objeto?


153

Como verifico a classe de um objeto no ambiente espaçado de nomes PHP sem especificar a classe espaçada de nomes completa.

Por exemplo, suponha que eu tenha uma biblioteca de objetos / Entidade / Contrato / Nome.

O código a seguir não funciona, pois get_class retorna a classe cheia de namespace.

If(get_class($object) == 'Name') {
... do this ...
}

A palavra-chave mágica do espaço para nome retorna o espaço para nome atual, que não será útil se o objeto testado tiver outro espaço para nome.

Eu poderia simplesmente especificar o nome completo da classe com espaços para nome, mas isso parece bloquear a estrutura do código. Também não é muito útil se eu quiser alterar o espaço para nome dinamicamente.

Alguém pode pensar em uma maneira eficiente de fazer isso. Eu acho que uma opção é regex.


Parece quase inútil porque diferentes espaços de nomes podem ter os mesmos nomes de classe definidos dentro deles, então como você vai lidar com isso? E isso ocorre porque o nome completo da classe qualificado é retornado em sua amostra
— Alma Do

Eu estou em um dispositivo móvel, então não posso enviar uma resposta decente, mas a solução é reflexo, especificamente ReflectionClass :: getShortName - php.net/manual/en/reflectionclass.getshortname.php
— lonesomeday

Para as pessoas que procuram um motivo para querer isso: pode ser útil em uma função auxiliar em uma classe base comum (ou seja, vários espaços para nome nunca são um problema nessa situação).
— Darren Cozinhe

Respostas:


182

Você pode fazer isso com reflexão. Especificamente, você pode usar o ReflectionClass::getShortNamemétodo, que obtém o nome da classe sem seu espaço para nome.

Primeiro, você precisa criar uma ReflectionClassinstância e, em seguida, chame o getShortNamemétodo dessa instância:

$reflect = new ReflectionClass($object);
if ($reflect->getShortName() === 'Name') {
    // do this
}

No entanto, não consigo imaginar muitas circunstâncias em que isso seria desejável. Se você deseja exigir que o objeto seja membro de uma determinada classe, é a maneira de testá-lo instanceof. Se você deseja uma maneira mais flexível de sinalizar certas restrições, a maneira de fazer isso é escrever uma interface e exigir que o código implemente essa interface. Novamente, a maneira correta de fazer isso é com instanceof. (Você pode fazer isso com ReflectionClass, mas teria um desempenho muito pior.)


1
@ Greg.Forbes Porque Tenantnão existe no espaço para nome atual. Tente em var_dump($tenant instanceof \Library\Entity\People\Tenant)vez disso. Além disso, investigue como usar o useoperador e o conceito geral por trás dos espaços para nome PHP!
— Loneomeday

3
Eu tive que adicionar uma barra na frente como esta$reflect = new \ReflectionClass($object);
— prograhammer

7
Geralmente, eu não gosto de fazer muito vodu ReflectionClass no meu aplicativo porque ele pode levar a resultados inesperados se for mal utilizado (métodos protegidos se tornam públicos etc.). Você pode usar substituição de string simples em constantes mágicas PHP em vez disso: str_replace(__NAMESPACE__ . '\\', '', __CLASS__);. Também é muito mais rápido, em termos de desempenho.
— precisa

2
@FranklinPStrube A menos que esteja faltando alguma coisa, isso obtém o nome abreviado da classe atual, em vez da classe do objeto. Concordo que o uso da reflexão geralmente significa que você está fazendo errado.
— Loneomeday

1
Muitas pessoas usam o Reflections para substituir a visibilidade dos membros, o que é MAU. Não faça isso! Mas afirmar que o uso de Reflexões em geral é Vodu e Fazer errado, dá às pessoas a impressão errada. Você não deve evitá-los, deve entendê-los e saber quando eles são benéficos e em que nível de abstração.
— 19418 Vanja D.

131

(new \ReflectionClass($obj))->getShortName(); é a melhor solução em relação ao desempenho.

Fiquei curioso para saber qual das soluções fornecidas é a mais rápida, por isso reuni um pequeno teste.

Resultados

Reflection: 1.967512512207 s ClassA
Basename:   2.6840535163879 s ClassA
Explode:    2.6507515668869 s ClassA

Código

namespace foo\bar\baz;

class ClassA{
    public function getClassExplode(){
        return explode('\\', static::class)[0];
    }

    public function getClassReflection(){
        return (new \ReflectionClass($this))->getShortName();
    }

    public function getClassBasename(){
        return basename(str_replace('\\', '/', static::class));
    }
}

$a = new ClassA();
$num = 100000;

$rounds = 10;
$res = array(
    "Reflection" => array(),
    "Basename" => array(),
    "Explode" => array(),
);

for($r = 0; $r < $rounds; $r++){

    $start = microtime(true);
    for($i = 0; $i < $num; $i++){
        $a->getClassReflection();
    }
    $end = microtime(true);
    $res["Reflection"][] = ($end-$start);

    $start = microtime(true);
    for($i = 0; $i < $num; $i++){
        $a->getClassBasename();
    }
    $end = microtime(true);
    $res["Basename"][] = ($end-$start);

    $start = microtime(true);
    for($i = 0; $i < $num; $i++){
        $a->getClassExplode();
    }
    $end = microtime(true);
    $res["Explode"][] = ($end-$start);
}

echo "Reflection: ".array_sum($res["Reflection"])/count($res["Reflection"])." s ".$a->getClassReflection()."\n";
echo "Basename: ".array_sum($res["Basename"])/count($res["Basename"])." s ".$a->getClassBasename()."\n";
echo "Explode: ".array_sum($res["Explode"])/count($res["Explode"])." s ".$a->getClassExplode()."\n";

Os resultados realmente me surpreenderam. Eu pensei que a solução de explosão seria o caminho mais rápido a seguir ...


1
Ótima resposta. Eu estava executando o mesmo código, mas obtive um resultado diferente (Macbook Pro i7, 16 GB de RAM). Reflexão: 0,382, Nome base: 0,380, Explodir: 0,399. Eu acho que depende do seu sistema o que é melhor ...
— Tobias Nyholm

4
Execute o PHP 10.000 vezes com esse código e você obterá um resultado melhor. O exemplo acima pode buscar o reflexo de algum pool, mas esse não é o comportamento usual dos aplicativos por aí. Eles só precisam disso uma ou duas vezes.
— LeMike

6
Maravilha I faz este teste é verdadeiro quando instanciar um ReflectionClass em um objeto mais substancial do que o pequeno objeto de Classe A, em seu teste ...
— Joe Green

2
executar apenas uma iteração em vez de 100000 fornece um resultado muito diferente: Reflexão: 1.0967254638672 100000th / s ClassA Nome de base: 0.81062316894531 100000th / s ClasseA Explode: 0.50067901611328 100000th / s ClassA
— mcmurphy

1
explodir ('\\', static :: class) [0]? não retorna a primeira parte do espaço para nome? deve retornar a última parte, não primeiro
— 2oppin 17/10/19

86

Adicionei substr ao teste de https://stackoverflow.com/a/25472778/2386943 e essa é a maneira mais rápida de testar (CentOS PHP 5.3.3, Ubuntu PHP 5.5.9), ambos com um i5.

$classNameWithNamespace=get_class($this);
return substr($classNameWithNamespace, strrpos($classNameWithNamespace, '\\')+1);

Resultados

Reflection: 0.068084406852722 s ClassA
Basename: 0.12301609516144 s ClassA
Explode: 0.14073524475098 s ClassA
Substring: 0.059865570068359 s ClassA 

Código

namespace foo\bar\baz;
class ClassA{
  public function getClassExplode(){
    $c = array_pop(explode('\\', get_class($this)));
    return $c;
  }

  public function getClassReflection(){
    $c = (new \ReflectionClass($this))->getShortName();
    return $c;
  }

  public function getClassBasename(){
    $c = basename(str_replace('\\', '/', get_class($this)));
    return $c;
  }

  public function getClassSubstring(){
    $classNameWithNamespace = get_class($this);
    return substr($classNameWithNamespace, strrpos($classNameWithNamespace, '\\')+1);
  }
}

$a = new ClassA();
$num = 100000;

$rounds = 10;
$res = array(
    "Reflection" => array(),
    "Basename" => array(),
    "Explode" => array(),
    "Substring" => array()
);

for($r = 0; $r < $rounds; $r++){

  $start = microtime(true);
  for($i = 0; $i < $num; $i++){
    $a->getClassReflection();
  }
  $end = microtime(true);
  $res["Reflection"][] = ($end-$start);

  $start = microtime(true);
  for($i = 0; $i < $num; $i++){
    $a->getClassBasename();
  }
  $end = microtime(true);
  $res["Basename"][] = ($end-$start);

  $start = microtime(true);
  for($i = 0; $i < $num; $i++){
    $a->getClassExplode();
  }
  $end = microtime(true);
  $res["Explode"][] = ($end-$start);

  $start = microtime(true);
  for($i = 0; $i < $num; $i++){
    $a->getClassSubstring();
  }
  $end = microtime(true);
  $res["Substring"][] = ($end-$start);
}

echo "Reflection: ".array_sum($res["Reflection"])/count($res["Reflection"])." s ".$a->getClassReflection()."\n";
echo "Basename: ".array_sum($res["Basename"])/count($res["Basename"])." s ".$a->getClassBasename()."\n";
echo "Explode: ".array_sum($res["Explode"])/count($res["Explode"])." s ".$a->getClassExplode()."\n";
echo "Substring: ".array_sum($res["Substring"])/count($res["Substring"])." s ".$a->getClassSubstring()."\n";

== ATUALIZAÇÃO ==

Como mencionado nos comentários de @MrBandersnatch, existe ainda uma maneira mais rápida de fazer isso:

return substr(strrchr(get_class($this), '\\'), 1);

Aqui estão os resultados atualizados dos testes com "SubstringStrChr" (economiza até 0,001 s):

Reflection: 0.073065280914307 s ClassA
Basename: 0.12585079669952 s ClassA
Explode: 0.14593172073364 s ClassA
Substring: 0.060415267944336 s ClassA
SubstringStrChr: 0.059880912303925 s ClassA

5
Só porque listamos por eficiência, achei a comparação mais rápida do teste fornecido neste substr da solução (strrchr (get_class ($ obj), '\\'), 1); Reflexão: 0.084223914146423 s ClassA - Nome básico: 0.13206427097321 s ClassA - Explodir: 0.15331919193268 s ClassA - Substring: 0.068068099021912 s ClassA - Strrchar: 0.06472008228302 s ClassA -
— ctatro85

Acabei de encontrar este tópico e adicionei uma referência adicional para testar str_replace(__NAMESPACE__ . '\\', '', __CLASS__);. Os resultados em uma máquina virtual fraca mostraram que ela era quase duas vezes mais rápida que todas elas. php -f bench.php Reflection: 0.44037771224976 s ClassA Basename: 0.48089025020599 s ClassA Explode: 0.54955270290375 s ClassA Substring: 0.38200764656067 s ClassA Frank's Custom Benchmark: 0.22782742977142 s ClassA
— precisa

1
@MrBandersnatch você está correto. Testei sua solução e ela me salvou cerca de 0,001 s. Eu atualizei minha resposta com a sua!
— Mabi

3
Aviso: este código não funciona com classes no espaço para nome global (ou seja: o nome completo é igual ao nome abreviado)! Conselho que eu a algo teste como: if ($pos = strrchr(static::class, '\\')) { .. } else { ... }.
— Tristan Jahier

1
Para fazê-lo funcionar também no espaço de nomes global, basta acrescentar o nome da classe com uma barra invertida :) - ie:$classNameShort = substr(strrchr('\\' . get_class($this), '\\'), 1);
— rosell.dk

25

Aqui está uma maneira mais fácil de fazer isso se você estiver usando a estrutura PHP do Laravel:

<?php

// usage anywhere
// returns HelloWorld
$name = class_basename('Path\To\YourClass\HelloWorld');

// usage inside a class
// returns HelloWorld
$name = class_basename(__CLASS__);

8
Esta não é uma função php embutida, parece uma função auxiliar fornecida pelo laravel.
— Steve Buzonas

6
Acho que ele disse que
— Scott

4
Obrigado, estou usando o Laravel e esta resposta me salvou um monte de tempo.
— 21717 Jeremy Wadhams


18

Eu uso isso:

basename(str_replace('\\', '/', get_class($object)));

Você também pode tentar: $ className = explode ('\\', basename (get_class ($ this))); $ className = array_pop ($ className); para obter o nome da classe simples. Ou use substr.
— 22614 Dompie

13
Funciona apenas no Windows No Windows, a barra (/) e a barra invertida () são usadas como caractere separador de diretório. Em outros ambientes, é a barra (/) php.net/manual/en/function.basename.php
— OzzyCzech 28/02

Eu consertei agora. Obrigado, @OzzyCzech.
— Theodore R. Smith

1
@OzzyCzech Acabei de descobrir isso ao passar do Windows para o Ubuntu .... enlouquecedor. Acabou usando a solução mencionada na atualização do MaBi.
— Chris Baker

@OzzyCzech Como é que funciona apenas no Windows? a pergunta era sobre o nome completo do espaço para nome, se não estiver errado há alguns anos atrás, e os espaços para nome não são específicos do sistema operacional e sempre com uma barra invertida como o separador de diretório do Windows.
— FantomX1

16

Para obter o nome abreviado como uma linha (desde o PHP 5.4 ):

echo (new ReflectionClass($obj))->getShortName();

É uma abordagem limpa e razoavelmente rápida .


1
Eu me pergunto como isso se compara a uma extração de string em benchmarks. Parece que isso seria muito mais lento.
— Contato não verificado

12

Eu me encontrei em uma situação única em instanceofque não podia ser usado (traços específicos no espaço de nome) e precisava do nome abreviado da maneira mais eficiente possível, para que eu próprio fiz uma pequena referência. Inclui todos os diferentes métodos e variações das respostas nesta pergunta.

$bench = new \xori\Benchmark(1000, 1000);     # https://github.com/Xorifelse/php-benchmark-closure
$shell = new \my\fancy\namespace\classname(); # Just an empty class named `classname` defined in the `\my\fancy\namespace\` namespace

$bench->register('strrpos', (function(){
    return substr(static::class, strrpos(static::class, '\\') + 1);
})->bindTo($shell));

$bench->register('safe strrpos', (function(){
    return substr(static::class, ($p = strrpos(static::class, '\\')) !== false ? $p + 1 : 0);
})->bindTo($shell));

$bench->register('strrchr', (function(){
    return substr(strrchr(static::class, '\\'), 1);
})->bindTo($shell));

$bench->register('reflection', (function(){
    return (new \ReflectionClass($this))->getShortName();
})->bindTo($shell));

$bench->register('reflection 2', (function($obj){
    return $obj->getShortName();
})->bindTo($shell), new \ReflectionClass($shell));

$bench->register('basename', (function(){
    return basename(str_replace('\\', '/', static::class));
})->bindTo($shell));

$bench->register('explode', (function(){
    $e = explode("\\", static::class);
    return end($e);
})->bindTo($shell));

$bench->register('slice', (function(){
    return join('',array_slice(explode('\\', static::class), -1));
})->bindTo($shell));    

print_r($bench->start());

Uma lista de todo o resultado está aqui, mas aqui estão os destaques:

  • Se você estiver indo para usar o reflexo de qualquer maneira, usando $obj->getShortName()é o método mais rápido no entanto ; usando apenas reflexão para obter o nome abreviado, é quase o método mais lento.
  • 'strrpos' pode retornar um valor errado se o objeto não estiver em um espaço para nome; 'safe strrpos' estiver um pouco mais lento, eu diria que esse é o vencedor.
  • Para torná-lo 'basename'compatível entre Linux e Windows, você precisa usar o str_replace()que torna esse método o mais lento de todos.

Uma tabela simplificada de resultados, a velocidade é medida em comparação com o método mais lento:

+-----------------+--------+
| registered name | speed  |
+-----------------+--------+
| reflection 2    | 70.75% |
| strrpos         | 60.38% |
| safe strrpos    | 57.69% |
| strrchr         | 54.88% |
| explode         | 46.60% |
| slice           | 37.02% |
| reflection      | 16.75% |
| basename        | 0.00%  |
+-----------------+--------+

8

Você pode usar explodepara separar o espaço endpara nome e obter o nome da classe:

$ex = explode("\\", get_class($object));
$className = end($ex);

7

Yii way

\yii\helpers\StringHelper::basename(get_class($model));

O Yii usa esse método em seu gerador de código Gii

Documentação do método

Este método é semelhante à função php basename (), exceto pelo fato de tratar \ e / como separadores de diretório, independentemente do sistema operacional. Este método foi criado principalmente para trabalhar em namespaces php. Ao trabalhar com caminhos de arquivos reais, o basename () do php deve funcionar bem para você. Nota: este método não está ciente do sistema de arquivos real ou dos componentes do caminho, como "..".

Mais Informações:

https://github.com/yiisoft/yii2/blob/master/framework/helpers/BaseStringHelper.php http://www.yiiframework.com/doc-2.0/yii-helpers-basestringhelper.html#basename()-detalhe


Bem-vindo ao Stack Overflow. Forneça mais informações para sua resposta. O que isso faz e como alguém pode usá-lo.
— Jens

1
Isso funcionou para mim no Windows, mas não no Linux, talvez porque os namespaces estejam na forma de barras invertidas dos diretórios do Windows '\', enquanto o linux basename considera os separadores de diretórios barras / '. Então, eu trabalhei com strtr. nome da base (strtr ($ class, '\\', '/'))
— FantomX1

6

Aqui está uma solução simples para PHP 5.4+

namespace {
    trait Names {
        public static function getNamespace() {
            return implode('\\', array_slice(explode('\\', get_called_class()), 0, -1));
        }

        public static function getBaseClassName() {
            return basename(str_replace('\\', '/', get_called_class()));
        }
    }
}

Qual será o retorno?

namespace x\y\z {
    class SomeClass {
        use \Names;
    }

    echo \x\y\z\SomeClass::getNamespace() . PHP_EOL; // x\y\z
    echo \x\y\z\SomeClass::getBaseClassName() . PHP_EOL; // SomeClass
}

O nome da classe e o espaço de nomes estendidos funcionam bem para:

namespace d\e\f {

    class DifferentClass extends \x\y\z\SomeClass {

    }

    echo \d\e\f\DifferentClass::getNamespace() . PHP_EOL; // d\e\f
    echo \d\e\f\DifferentClass::getBaseClassName() . PHP_EOL; // DifferentClass
}

E a classe no namespace global?

namespace {

    class ClassWithoutNamespace {
        use \Names;
    }

    echo ClassWithoutNamespace::getNamespace() . PHP_EOL; // empty string
    echo ClassWithoutNamespace::getBaseClassName() . PHP_EOL; // ClassWithoutNamespace
}

3

Se você precisar saber o nome da classe que foi chamado de dentro de uma classe e não desejar o espaço para nome, use este

$calledClass = get_called_class();
$name = strpos($calledClass, '\\') === false ?
    $calledClass : substr($calledClass, strrpos($calledClass, '\\') + 1);

Isso é ótimo quando você tem um método dentro de uma classe que é estendido por outras classes. Além disso, isso também funciona se os namespaces não forem usados.

Exemplo:

<?php
namespace One\Two {
    class foo
    {
        public function foo()
        {
            $calledClass = get_called_class();
            $name = strpos($calledClass, '\\') === false ?
                $calledClass : substr($calledClass, strrpos($calledClass, '\\') + 1);

            var_dump($name);
        }
    }
}

namespace Three {
    class bar extends \One\Two\foo
    {
        public function bar()
        {
            $this->foo();
        }
    }
}

namespace {
    (new One\Two\foo)->foo();
    (new Three\bar)->bar();
}

// test.php:11:string 'foo' (length=3)
// test.php:11:string 'bar' (length=3)

2

Com base na resposta de @MaBi, fiz o seguinte:

trait ClassShortNameTrait
{
    public static function getClassShortName()
    {
        if ($pos = strrchr(static::class, '\\')) {
            return substr($pos, 1);
        } else {
            return static::class;
        }
    }
}

Que você pode usar assim:

namespace Foo\Bar\Baz;

class A
{
    use ClassShortNameTrait;
}

A::classretorna Foo\Bar\Baz\A, mas A::getClassShortName()retorna A.

Funciona para PHP> = 5.5.


2

Eu sei que este é um post antigo, mas é isso que eu uso - mais rápido do que o post acima, basta chamar esse método da sua classe, muito mais rápido do que usar o Reflection

namespace Foo\Bar\Baz;

class Test {
    public function getClass() {
        return str_replace(__NAMESPACE__.'\\', '', static::class);
    }
}

Infelizmente, isso só funciona se você estiver chamando na classe cujo nome deseja, e não em qualquer nome de classe como uma string.
— jurchiks 29/03

1

Encontrado na página de documentação de get_class , onde foi postada por mim no nwhiting dot com .

function get_class_name($object = null)
{
    if (!is_object($object) && !is_string($object)) {
        return false;
    }

    $class = explode('\\', (is_string($object) ? $object : get_class($object)));
    return $class[count($class) - 1];
}

Mas a idéia de espaços para nome é estruturar seu código. Isso também significa que você pode ter classes com o mesmo nome em vários espaços para nome. Então, teoricamente, o objeto que você passa pode ter o nome da classe (despojado), enquanto continua sendo um objeto totalmente diferente do que você espera.

Além disso, convém verificar uma classe base específica , caso em get_classque não faz o truque. Você pode querer verificar o operador instanceof.


1

Você pode obter um resultado inesperado quando a classe não possui um espaço para nome. Ou seja , get_classretorna Foo, então $baseClassseria oo.

$baseClass = substr(strrchr(get_class($this), '\\'), 1);

Isso pode ser facilmente corrigido prefixando get_classuma barra invertida:

$baseClass = substr(strrchr('\\'.get_class($this), '\\'), 1);

Agora também as classes sem um espaço para nome retornarão o valor correto.


1

Um bom e velho regex parece ser mais rápido que a maioria dos métodos mostrados anteriormente:

// both of the below calls will output: ShortClassName

echo preg_replace('/.*\\\\/', '', 'ShortClassName');
echo preg_replace('/.*\\\\/', '', 'SomeNamespace\SomePath\ShortClassName');

Portanto, isso funciona mesmo quando você fornece um nome de classe curto ou um nome de classe totalmente qualificado (canônico).

O que a regex faz é que consome todos os caracteres anteriores até que o último separador seja encontrado (que também é consumido). Portanto, a sequência restante será o nome curto da classe.

Se você deseja usar um separador diferente (por exemplo, /), basta usar esse separador. Lembre-se de escapar da barra invertida (ex. \) E também do padrão char (ex. /) No padrão de entrada.


1

Como "ReflectionClass" pode ser uma versão dependente, basta usar o seguinte:

if(class_basename(get_class($object)) == 'Name') {
... do this ...
}

ou até claro

if(class_basename(ClassName::class) == 'ClassName') {
... do this ...
}

0

Citando php.net:

No Windows, a barra (/) e a barra invertida () são usadas como caractere separador de diretório. Em outros ambientes, é a barra (/).

Com base nessas informações e na expansão da resposta da arzzzen, isso deve funcionar nos sistemas Windows e Nix *:

<?php

if (basename(str_replace('\\', '/', get_class($object))) == 'Name') {
    // ... do this ...
}

Nota: Fiz um benchmark ReflectionClasscontra basename+str_replace+get_classe o uso da reflexão é aproximadamente 20% mais rápido que o uso da abordagem de nome de base, mas o YMMV.


0

A solução mais rápida e fácil que funciona em qualquer ambiente é:

<?php

namespace \My\Awesome\Namespace;

class Foo {

  private $shortName;

  public function fastShortName() {
    if ($this->shortName === null) {
      $this->shortName = explode("\\", static::class);
      $this->shortName = end($this->shortName);
    }
    return $this->shortName;
  }

  public function shortName() {
    return basename(strtr(static::class, "\\", "/"));
  }

}

echo (new Foo())->shortName(); // "Foo"

?>

1
É por isso que eu gostaria que o PHP tivesse operadores de informações de classe interna. Instanciar um refletor externo para fazer o que deveria ser tão simples quanto $Object->__class->getShortName()realmente me irrita com o PHP. Sua abordagem funciona, mas agora você está colocando métodos concretos em suas aulas apenas para expor o que deve ser uma construção de linguagem.
— AgmLauncher

PHP sem funções "concretas" (ou deveríamos chamá-las de procedimentos) é impossível. Vamos esperar pelo PHP 6 (bem, se houver).
— Fleshgrinder

0
$shortClassName = join('',array_slice(explode('\\', $longClassName), -1));

0

Se você está apenas removendo os espaços para nome e quiser algo após o último \ em um nome de classe com espaço para nome (ou apenas o nome se não houver '\'), poderá fazer algo assim:

$base_class = preg_replace('/^([\w\\\\]+\\\\)?([^\\\\]+)$/', '$2', get_class($myobject));

Basicamente, é regex obter qualquer combinação de caracteres ou barras invertidas e, até a última barra invertida, retornar apenas os caracteres que não são invertidos e até o final da string. Adicionando o? depois que o primeiro agrupamento significa que, se a correspondência de padrões não existir, ela retornará a sequência completa.


0

Mais rápido que eu encontrei aqui para PHP 7.2onUbubntu 18.04

preg_replace('/^(\w+\\\)*/', '', static::class)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.