オブジェクトの修飾されていない(短い)クラス名を取得するにはどうすればよいですか?


153

名前空間の完全なクラスを指定せずに、PHP名前空間環境内のオブジェクトのクラスを確認するにはどうすればよいですか。

たとえば、オブジェクトライブラリ/エンティティ/契約/名前があるとします。

get_classが完全な名前空間クラスを返すため、次のコードは機能しません。

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

名前空間のmagicキーワードは、現在の名前空間を返します。これは、テストされたオブジェクトに別の名前空間がある場合は使用されません。

名前空間で完全なクラス名を指定することもできますが、これはコードの構造に固定されているようです。名前空間を動的に変更したい場合もあまり役に立ちません。

誰でもこれを行うための効率的な方法を考えることができますか?1つのオプションは正規表現だと思います。


異なる名前空間には同じクラス名が定義されている可能性があるので、ほとんど意味がないように見えます。これは、サンプルで完全修飾クラス名が返されるためです
Alma Do

私はモバイルデバイスを使用しているため、適切な回答を送信できませんが、解決策はリフレクションです。具体的には、ReflectionClass :: getShortName-php.net/manual/en/reflectionclass.getshortname.php
lonesomeday

これが必要な理由を探している人にとって:これは、共通の基本クラスのヘルパー関数で役立つ場合があります(つまり、この状況では複数の名前空間が問題になることはありません)。
Darren Cook

回答:


182

リフレクションでこれを行うことができます。具体的にReflectionClass::getShortNameは、名前空間なしでクラスの名前を取得するメソッドを使用できます。

まず、ReflectionClassインスタンスを作成してからgetShortName、そのインスタンスのメソッドを呼び出す必要があります。

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

しかし、これが望ましい状況はあまり想像できません。オブジェクトが特定のクラスのメンバーであることを要求する場合、それをテストする方法はを使用することですinstanceof。特定の制約を通知するより柔軟な方法が必要な場合、それを行う方法は、インターフェイスを記述し、コードがそのインターフェイスを実装することを要求することです。繰り返しますが、これを行う正しい方法はを使用することinstanceofです。(でそれを行うことができますがReflectionClass、パフォーマンスははるかに悪くなります。)


1
@ Greg.Forbes Tenantは現在の名前空間に存在しないためです。var_dump($tenant instanceof \Library\Entity\People\Tenant)代わりに試してください。また、use演算子の使用方法と、PHP名前空間の背後にある一般的な概念も調べてください。
lonesomeday

3
私はこのように前にスラッシュを追加しなければなり$reflect = new \ReflectionClass($object);
ませんでした

7
私は通常、アプリケーションで多くのReflectionClassブードゥーを実行することを好みません。これは、誤って使用した場合(保護されたメソッドがパブリックになるなど)に予期しない結果が生じる可能性があるためです。代わりに、PHPマジック定数で単純な文字列置換を使用できますstr_replace(__NAMESPACE__ . '\\', '', __CLASS__);。また、パフォーマンスも大幅に向上します。
Franklin P Strube 2015

2
@FranklinPStrube何か不足している場合を除き、オブジェクトのクラスではなく、現在のクラスの短い名前が取得されます。リフレクションの使用は通常、間違っていることを意味することに同意します。
lonesomeday

1
多くの人々は、メンバーの可視性のオーバーライドにリフレクションを使用しています。これは悪いことです。やめてください!しかし、リフレクションの一般的な使用はブードゥーであり、それを間違っていると述べることは人々に間違った印象を与えます。それらを避けるべきではありません。それらを理解し、それらがいつ有益で、どのレベルの抽象化になるかを理解する必要があります。
Vanja D.

131

(new \ReflectionClass($obj))->getShortName(); パフォーマンスに関しては最適なソリューションです。

提供されているソリューションのどれが最も速いのか知りたくて、少しテストをまとめました。

結果

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

コード

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";

結果は実際に私を驚かせた。私は爆発ソリューションが最も速い方法だと思っていました...


1
すばらしい答えです。まったく同じコードを実行していましたが、結果が異なりました(Macbook Pro i7、16 GB RAM)。リフレクション:0.382、ベース名:0.380、分解:0.399。何が最良かはシステムに依存すると思います...
Tobias Nyholm

4
そのコードでPHP 10 000回実行すると、より良い結果が得られます。上記はいくつかのプールからリフレクションをフェッチするかもしれませんが、これはそこにあるアプリケーションの通常の動作ではありません。彼らは一度か二度それを必要とするだけです。
LeMike、2014年

6
私の不思議テストのクラスAの小さなオブジェクトよりもより実質的なオブジェクトにReflectionClassのインスタンスを作成する際に...本当、このテストホールドを行います
ジョー・グリーン

2
100000の代わりに1回の反復だけを実行すると、結果が大きく異なります。反射:1.0967254638672 100000th / s ClassAベース名:0.81062316894531 100000th / s ClassA分解:0.50067901611328 100000th / s ClassA
mcmurphy

1
explode( '\\'、static :: class)[0]?名前空間の最初の部分を返しませんか?最初ではなく最後の部分を返す必要があります
2oppin '17 / 10/17

86

https://stackoverflow.com/a/25472778/2386943のテストにsubstrを追加しました 。これは、i5で両方をテストできる最も速い方法(CentOS PHP 5.3.3、Ubuntu PHP 5.5.9)です。

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

結果

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

コード

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";

==更新==

@MrBandersnatchのコメントで述べたように、これを行うためのさらに高速な方法があります。

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

以下は、 "SubstringStrChr"で更新されたテスト結果です(最大約0.001秒節約):

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
効率を上げるためにリストしたからといって、これが最速であることがわかりました。このソリューションで提供されているテストとの比較substr(strrchr(get_class($ obj)、 '\\')、1); リフレクション:0.084223914146423 s ClassA-ベース名:0.13206427097321 s ClassA-分解:0.15331919193268 s ClassA-サブストリング:0.068068099021912 s ClassA-Strrchar:0.06472008228302 s
ClassA-– ctatro85

私はこのスレッドに出くわし、テストするための追加のベンチマークを追加しましたstr_replace(__NAMESPACE__ . '\\', '', __CLASS__);。弱い仮想マシンでの結果は、これらすべての仮想マシンのほぼ2倍の速さを示しました。 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
フランクリンP Strube 2015

1
@MrBandersnatch正解です。私はあなたのソリューションをテストしました、そしてそれは私に約0.001秒を節約しました。私はあなたの答えを更新しました!
MaBi 2015年

3
警告:このコードは、グローバル名前空間のクラスでは機能しません(つまり、フルネームはショートネームと同じです)。次のようなものをテストすることをお勧めしますif ($pos = strrchr(static::class, '\\')) { .. } else { ... }
Tristan Jahier 2016年

1
グローバルネームスペースでも機能させるには、クラス名の前にバックスラッシュを付けます:)-すなわち:$classNameShort = substr(strrchr('\\' . get_class($this), '\\'), 1);
rosell.dk

25

Laravel PHPフレームワークを使用している場合、これを行うより簡単な方法を次に示します。

<?php

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

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

8
これは組み込みのphp関数ではなく、laravelが提供するヘルパー関数のように見えます。
Steve Buzonas 16年

6
私は彼が言ったと思います
スコット

4
おかげで、私はLaravelを使用しています。この回答により、時間を大幅に節約できました。
Jeremy Wadhams 2017


18

私はこれを使います:

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

$ className = explode( '\\'、basename(get_class($ this)));を試すこともできます。$ className = array_pop($ className); プレーンなクラス名を取得します。または、substrを使用します。
dompie 2014

13
Windowsでのみ機能します。Windowsでは、スラッシュ(/)とバックスラッシュ()の両方がディレクトリ区切り文字として使用されます。他の環境では、スラッシュ(/)です。php.net
OzzyCzech

今修正しました。ありがとう、@ OzzyCzech。
セオドアR.スミス

1
@OzzyCzech WindowsからUbuntuに移動しているときに、これに遭遇しました。MaBiのアップデートで言及されたソリューションを使用して巻き上げます。
クリスベイカー

@OzzyCzech Windowsでのみ機能するのはなぜですか?質問は、私も何年も前に間違っていなかった場合の完全修飾名前空間名に関するものであり、名前空間はOS固有ではなく、常にWindowsのディレクトリ区切り記号のようなバックスラッシュが付いています。
FantomX1

16

短い名前をワンライナーとして取得するには(PHP 5.4以降):

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

それは、クリーンなアプローチと合理的な高速です。


1
これがベンチマークの文字列抽出とどのように比較されるのかと思います。これはずっと遅いようです。
未確認の連絡

12

instanceof使用できない特殊な状況(特に名前空間の特性)に気づき、可能な限り最も効率的な方法で短い名前が必要になったので、独自のベンチマークを行いました。これには、この質問の回答からのさまざまな方法とバリエーションがすべて含まれています。

$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());

結果全体のリストはここにありますが、ここにハイライトがあります:

  • 場合あなたはとにかくリフレクションを使用しようとしている、使用しては$obj->getShortName()最速の方法です、リフレクションを使用してのみ、それはほとんど最も遅いメソッドである短い名前を取得します。
  • 'strrpos'オブジェクトが名前空間にない場合、間違った値を返す可能性'safe strrpos'があるため、少し遅いのですが、これが勝者です。
  • 'basename'LinuxとWindowsの間で互換性を持たstr_replace()せるには、この方法が最も遅い方法を使用する必要があります。

結果の簡略化された表、速度は最も遅い方法と比較して測定されます。

+-----------------+--------+
| 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

を使用explodeして名前空間を分離しend、クラス名を取得できます。

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

7

Yiiウェイ

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

YiiはGiiコードジェネレーターでこのメソッドを使用しています

メソッドのドキュメント

このメソッドは、オペレーティングシステムに関係なく、\と/の両方をディレクトリセパレータとして扱うことを除いて、php関数basename()に似ています。このメソッドは、主にphp名前空間で動作するように作成されました。実際のファイルパスを操作する場合、phpのbasename()が正常に機能するはずです。注:このメソッドは、実際のファイルシステムや「..」などのパスコンポーネントを認識しません。

詳しくは:

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


Stack Overflowへようこそ。回答の詳細情報を入力してください。これは何をし、どのように使用することができますか。
イェンス

1
これは、Windowsでは機能しましたが、Linuxでは機能しませんでした。おそらく、名前空間がWindowsディレクトリのバックスラッシュ '\'の形式になっているためです。だから私はstrtrでそれを回避しました。basename(strtr($ class、 '\\'、 '/'))
FantomX1

6

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()));
        }
    }
}

何が返却されますか?

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
}

拡張されたクラス名と名前空間は、次の目的に適しています。

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
}

グローバル名前空間のクラスはどうですか?

namespace {

    class ClassWithoutNamespace {
        use \Names;
    }

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

3

クラス内から呼び出されたクラス名を知る必要があり、名前空間が必要ない場合は、これを使用できます

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

これは、クラス内に他のクラスによって拡張されたメソッドがある場合に最適です。さらに、名前空間がまったく使用されていない場合にも機能します。

例:

<?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

@MaBiの答えに基づいて、私はこれを作りました:

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

あなたはそのように使うことができます:

namespace Foo\Bar\Baz;

class A
{
    use ClassShortNameTrait;
}

A::classはを返しますがFoo\Bar\Baz\A、をA::getClassShortName()返しますA

PHP> = 5.5で動作します。


2

私はこれが古い投稿であることを知っていますが、これは私が使用するものです-上記のすべての投稿よりも速く、クラスからこのメソッドを呼び出すだけで、Reflectionを使用するよりもはるかに高速です

namespace Foo\Bar\Baz;

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

残念ながら、これは、文字列としてのクラス名だけでなく、必要な名前のクラスで呼び出す場合にのみ機能します。
jurchiks

1

get_classドキュメントページにあり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];
}

しかし、名前空間のアイデアは、コードを構造化することです。つまり、複数の名前空間に同じ名前のクラスを含めることができます。したがって、理論的には、渡したオブジェクトに(ストリップされた)クラス名が付いていても、予想とはまったく異なるオブジェクトである可能性があります。

それ以外に、特定の基本クラスを確認することもできますが、その場合get_classはまったく効果がありません。オペレーターを確認することをお勧めしinstanceofます。


1

クラスに名前空間がない場合、予期しない結果が生じる可能性があります。すなわちget_class戻りますFoo、それから$baseClassでしょうoo

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

これはget_class、バックスラッシュを前に付けることで簡単に修正できます。

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

名前空間のないクラスも正しい値を返します。


1

古き良き正規表現は、前に示したほとんどの方法よりも高速であるようです。

// both of the below calls will output: ShortClassName

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

したがって、これは、短いクラス名または完全修飾(正規)クラス名を指定した場合でも機能します。

正規表現は、最後のセパレーターが見つかるまで(これも消費されます)、それまでのすべての文字を消費するということです。したがって、残りの文字列は短いクラス名になります。

別のセパレーター(例:/)を使用したい場合は、代わりにそのセパレーターを使用してください。入力パターンでは、バックスラッシュ(つまり\)とパターン文字(つまり/)をエスケープすることを忘れないでください。


1

"ReflectionClass"はバージョンに依存する可能性があるため、以下を使用するだけです。

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

またはクリアさえ

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

0

php.netの引用:

Windowsでは、スラッシュ(/)とバックスラッシュ()の両方がディレクトリ区切り文字として使用されます。他の環境では、スラッシュ(/)です。

この情報に基づいて、arzzzenの回答から拡張すると、これはWindowsシステムとNix *システムの両方で機能するはずです。

<?php

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

注:私はReflectionClass反対のベンチマークを行いbasename+str_replace+get_class、リフレクションを使用すると、ベース名アプローチを使用するよりも約20%高速ですが、YMMVです。


0

あらゆる環境で機能する、最も速く、最も簡単なソリューションは次のとおりです。

<?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
これが、PHPに内部クラス情報演算子があることを望んでいる理由です。外部リフレクターをインスタンス化して、$Object->__class->getShortName()PHPに腹を立てるほど簡単なことをします。あなたのアプローチは機能しますが、今あなたはクラスに具体的なメソッドを入れて、言語構造であるべきものを公開しています。
AgmLauncher

「具体的な」(または手続き型の)関数を持たないPHPは不可能です。PHP 6が来るのを待ちましょう(まあ、そうなったとしても)。
Fleshgrinder 2014


0

名前空間を削除するだけで、名前空間のあるクラス名の最後の\の後に何かが必要な場合(または '\'がない場合は名前だけ)、次のようにすることができます。

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

基本的に、文字またはバックスラッシュの任意の組み合わせを最後のバックスラッシュまで取得し、次にバックスラッシュ以外の文字のみを返し、文字列の最後まで取得するのは正規表現です。?最初のグループ化の後は、パターンマッチが存在しない場合、完全な文字列を返すだけです。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.