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.

Greg.Forbes
fonte
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.)

lonesomeday
fonte
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 ...

Hirnhamster
fonte
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
MaBi
fonte
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__);
spetsnaz
fonte
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)));
arzzzen
fonte
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 .

flori
fonte
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%  |
+-----------------+--------+
Xorifelse
fonte
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);
m13r
fonte
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

mariovials
fonte
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
}
OzzyCzech
fonte
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)
Nino Škopac
fonte
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.

Tristan Jahier
fonte
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);
    }
}
Seth
fonte
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.

GolezTrol
fonte
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.

Tim
fonte
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.

Eugen Mihailescu
fonte
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 ...
}
Martin Tonev
fonte
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.

noisebleed
fonte
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"

?>
Triturador de Carne
fonte
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));
malhal
fonte
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.

Scott
fonte
0

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

preg_replace('/^(\w+\\\)*/', '', static::class)
Vasilii Suricov
fonte