@@ -2918,6 +2918,100 @@ class PropertyInfo extends VariableLike
29182918 public bool $isDocReadonly;
29192919 public bool $isVirtual;
29202920
2921+ // Map possible variable names to the known string constant, see
2922+ // ZEND_KNOWN_STRINGS
2923+ private const PHP_80_KNOWN = [
2924+ "file" => "ZEND_STR_FILE",
2925+ "line" => "ZEND_STR_LINE",
2926+ "function" => "ZEND_STR_FUNCTION",
2927+ "class" => "ZEND_STR_CLASS",
2928+ "object" => "ZEND_STR_OBJECT",
2929+ "type" => "ZEND_STR_TYPE",
2930+ // ZEND_STR_OBJECT_OPERATOR and ZEND_STR_PAAMAYIM_NEKUDOTAYIM are
2931+ // not valid variable names
2932+ "args" => "ZEND_STR_ARGS",
2933+ "unknown" => "ZEND_STR_UNKNOWN",
2934+ "eval" => "ZEND_STR_EVAL",
2935+ "include" => "ZEND_STR_INCLUDE",
2936+ "require" => "ZEND_STR_REQUIRE",
2937+ "include_once" => "ZEND_STR_INCLUDE_ONCE",
2938+ "require_once" => "ZEND_STR_REQUIRE_ONCE",
2939+ "scalar" => "ZEND_STR_SCALAR",
2940+ "error_reporting" => "ZEND_STR_ERROR_REPORTING",
2941+ "static" => "ZEND_STR_STATIC",
2942+ // ZEND_STR_THIS cannot be used since $this cannot be reassigned
2943+ "value" => "ZEND_STR_VALUE",
2944+ "key" => "ZEND_STR_KEY",
2945+ "__invoke" => "ZEND_STR_MAGIC_INVOKE",
2946+ "previous" => "ZEND_STR_PREVIOUS",
2947+ "code" => "ZEND_STR_CODE",
2948+ "message" => "ZEND_STR_MESSAGE",
2949+ "severity" => "ZEND_STR_SEVERITY",
2950+ "string" => "ZEND_STR_STRING",
2951+ "trace" => "ZEND_STR_TRACE",
2952+ "scheme" => "ZEND_STR_SCHEME",
2953+ "host" => "ZEND_STR_HOST",
2954+ "port" => "ZEND_STR_PORT",
2955+ "user" => "ZEND_STR_USER",
2956+ "pass" => "ZEND_STR_PASS",
2957+ "path" => "ZEND_STR_PATH",
2958+ "query" => "ZEND_STR_QUERY",
2959+ "fragment" => "ZEND_STR_FRAGMENT",
2960+ "NULL" => "ZEND_STR_NULL",
2961+ "boolean" => "ZEND_STR_BOOLEAN",
2962+ "integer" => "ZEND_STR_INTEGER",
2963+ "double" => "ZEND_STR_DOUBLE",
2964+ "array" => "ZEND_STR_ARRAY",
2965+ "resource" => "ZEND_STR_RESOURCE",
2966+ // ZEND_STR_CLOSED_RESOURCE has a space in it
2967+ "name" => "ZEND_STR_NAME",
2968+ // ZEND_STR_ARGV and ZEND_STR_ARGC are superglobals that wouldn't be
2969+ // variable names
2970+ "Array" => "ZEND_STR_ARRAY_CAPITALIZED",
2971+ "bool" => "ZEND_STR_BOOL",
2972+ "int" => "ZEND_STR_INT",
2973+ "float" => "ZEND_STR_FLOAT",
2974+ "callable" => "ZEND_STR_CALLABLE",
2975+ "iterable" => "ZEND_STR_ITERABLE",
2976+ "void" => "ZEND_STR_VOID",
2977+ "false" => "ZEND_STR_FALSE",
2978+ "null" => "ZEND_STR_NULL_LOWERCASE",
2979+ "mixed" => "ZEND_STR_MIXED",
2980+ ];
2981+
2982+ // NEW in 8.1
2983+ private const PHP_81_KNOWN = [
2984+ "Unknown" => "ZEND_STR_UNKNOWN_CAPITALIZED",
2985+ "never" => "ZEND_STR_NEVER",
2986+ "__sleep" => "ZEND_STR_SLEEP",
2987+ "__wakeup" => "ZEND_STR_WAKEUP",
2988+ "cases" => "ZEND_STR_CASES",
2989+ "from" => "ZEND_STR_FROM",
2990+ "tryFrom" => "ZEND_STR_TRYFROM",
2991+ "tryfrom" => "ZEND_STR_TRYFROM_LOWERCASE",
2992+ // Omit ZEND_STR_AUTOGLOBAL_(SERVER|ENV|REQUEST)
2993+ ];
2994+
2995+ // NEW in 8.2
2996+ private const PHP_82_KNOWN = [
2997+ "true" => "ZEND_STR_TRUE",
2998+ "Traversable" => "ZEND_STR_TRAVERSABLE",
2999+ "count" => "ZEND_STR_COUNT",
3000+ "SensitiveParameter" => "ZEND_STR_SENSITIVEPARAMETER",
3001+ ];
3002+
3003+ // Only new string in 8.3 is ZEND_STR_CONST_EXPR_PLACEHOLDER which is
3004+ // not a valid variable name ("[constant expression]")
3005+
3006+ // NEW in 8.4
3007+ private const PHP_84_KNOWN = [
3008+ "exit" => "ZEND_STR_EXIT",
3009+ "Deprecated" => "ZEND_STR_DEPRECATED_CAPITALIZED",
3010+ "since" => "ZEND_STR_SINCE",
3011+ "get" => "ZEND_STR_GET",
3012+ "set" => "ZEND_STR_SET",
3013+ ];
3014+
29213015 /**
29223016 * @var AttributeInfo[] $attributes
29233017 */
@@ -3003,8 +3097,8 @@ public function getDeclaration(array $allConstInfos): string {
30033097 $code .= $defaultValue->initializeZval($zvalName);
30043098 }
30053099
3006- $code .= "\tzend_string *property_{$propertyName}_name = zend_string_init(\"$propertyName\", sizeof(\" $propertyName\") - 1, 1);\n" ;
3007- $nameCode = "property_{$propertyName}_name" ;
3100+ [$stringInit, $nameCode, $stringRelease] = $this->getString( $propertyName) ;
3101+ $code .= $stringInit ;
30083102
30093103 if ($this->exposedDocComment) {
30103104 $commentCode = "property_{$propertyName}_comment";
@@ -3035,11 +3129,61 @@ public function getDeclaration(array $allConstInfos): string {
30353129 );
30363130 $code .= implode("", $flagsCode);
30373131
3038- $code .= "\tzend_string_release(property_{$propertyName}_name);\n" ;
3132+ $code .= $stringRelease ;
30393133
30403134 return $code;
30413135 }
30423136
3137+ /**
3138+ * Get an array of three strings:
3139+ * - declaration of zend_string, if needed, or empty otherwise
3140+ * - usage of that zend_string, or usage with ZSTR_KNOWN()
3141+ * - freeing the zend_string, if needed
3142+ *
3143+ * @param string $propName
3144+ * @return string[]
3145+ */
3146+ private function getString(string $propName): array {
3147+ // Generally strings will not be known
3148+ $nameCode = "property_{$propName}_name";
3149+ $result = [
3150+ "\tzend_string *$nameCode = zend_string_init(\"$propName\", sizeof(\"$propName\") - 1, 1);\n",
3151+ $nameCode,
3152+ "\tzend_string_release($nameCode);\n"
3153+ ];
3154+ // If not set, use the current latest version
3155+ $allVersions = ALL_PHP_VERSION_IDS;
3156+ $minPhp = $phpVersionIdMinimumCompatibility ?? end($allVersions);
3157+ if ($minPhp < PHP_80_VERSION_ID) {
3158+ // No known strings in 7.0
3159+ return $result;
3160+ }
3161+ $include = self::PHP_80_KNOWN;
3162+ switch ($minPhp) {
3163+ case PHP_84_VERSION_ID:
3164+ $include = array_merge($include, self::PHP_84_KNOWN);
3165+ // Intentional fall through
3166+
3167+ case PHP_83_VERSION_ID:
3168+ case PHP_82_VERSION_ID:
3169+ $include = array_merge($include, self::PHP_82_KNOWN);
3170+ // Intentional fall through
3171+
3172+ case PHP_81_VERSION_ID:
3173+ $include = array_merge($include, self::PHP_81_KNOWN);
3174+ break;
3175+ }
3176+ if (array_key_exists($propName,$include)) {
3177+ $knownStr = $include[$propName];
3178+ return [
3179+ '',
3180+ "ZSTR_KNOWN($knownStr)",
3181+ '',
3182+ ];
3183+ }
3184+ return $result;
3185+ }
3186+
30433187 /**
30443188 * @return array<int, string[]>
30453189 */
0 commit comments