diff --git a/reference/filesystem/functions/touch.xml b/reference/filesystem/functions/touch.xml
index eebaf7c8d8a6..249a3175f373 100644
--- a/reference/filesystem/functions/touch.xml
+++ b/reference/filesystem/functions/touch.xml
@@ -135,6 +135,27 @@ if (!touch('some_file.txt', $time)) {
&reftitle.notes;
¬e.filesystem-time-res;
+
+
+ Updates to the mtime or atime
+ of a file will not be reflected immediately in filesystem operations
+ such as filemtime. That's because the information
+ is cached, and this function does not automatically clear the cache.
+ To have changes reflected in the application immediately, call
+ clearstatcache on the file.
+
+
+
+
+
+ &reftitle.seealso;
+
+
+ clearstatcache
+ fileatime
+ filemtime
+
+
diff --git a/reference/reflection/book.xml b/reference/reflection/book.xml
index bd371343a58a..162437603e6e 100644
--- a/reference/reflection/book.xml
+++ b/reference/reflection/book.xml
@@ -49,6 +49,7 @@
&reference.reflection.reflectionattribute;
&reference.reflection.reflector;
&reference.reflection.reflectionexception;
+ &reference.reflection.propertyhooktype;
diff --git a/reference/reflection/propertyhooktype.xml b/reference/reflection/propertyhooktype.xml
new file mode 100644
index 000000000000..98bc18351509
--- /dev/null
+++ b/reference/reflection/propertyhooktype.xml
@@ -0,0 +1,57 @@
+
+
+ The \PropertyHookType Enum
+ \PropertyHookType
+
+
+
+ &reftitle.intro;
+
+ The \PropertyHookType enum lists the legal
+ types of property hook.
+
+
+
+
+ &reftitle.enumsynopsis;
+
+
+ \PropertyHookType
+
+
+ Get
+
+ Indicates a get hook.
+
+
+
+
+ Set
+
+ Indicates a set hook.
+
+
+
+
+
+
+
diff --git a/reference/reflection/reflectionproperty/gethook.xml b/reference/reflection/reflectionproperty/gethook.xml
new file mode 100644
index 000000000000..21b9b237c976
--- /dev/null
+++ b/reference/reflection/reflectionproperty/gethook.xml
@@ -0,0 +1,91 @@
+
+
+
+ ReflectionProperty::getHook
+ Returns a reflection object for a specified hook.
+
+
+
+ &reftitle.description;
+
+ publicReflectionMethodnullReflectionProperty::getHook
+ PropertyHookTypetype
+
+
+ Gets the reflection of the property's hook, if any.
+
+
+
+
+ &reftitle.parameters;
+
+
+ PropertyHookType
+
+
+ The type of hook to request.
+
+
+
+
+
+
+
+ &reftitle.returnvalues;
+
+ If the requested hook is defined, a ReflectionMethod instance will be returned.
+ If not, the method will return &null;
+
+
+
+
+ &reftitle.examples;
+
+ ReflectionProperty::getHook example
+
+ "Name here"; }
+}
+
+$rClass = new \ReflectionClass(Example::class);
+$rProp = $rClass->getProperty('name');
+var_dump($rProp->getHook(PropertyHookType::Get));
+var_dump($rProp->getHook(PropertyHookType::Set));
+?>
+]]>
+
+
+
+
+
+ &reftitle.seealso;
+
+ ReflectionMethod
+ PropertyHookType
+
+
+
+
+
diff --git a/reference/reflection/reflectionproperty/gethooks.xml b/reference/reflection/reflectionproperty/gethooks.xml
new file mode 100644
index 000000000000..6c920172962a
--- /dev/null
+++ b/reference/reflection/reflectionproperty/gethooks.xml
@@ -0,0 +1,91 @@
+
+
+
+ ReflectionProperty::getHooks
+ Returns an array of all hooks on this property
+
+
+
+ &reftitle.description;
+
+ publicarrayReflectionProperty::getHooks
+
+
+
+ Returns a list of all hooks on this property.
+
+
+
+
+ &reftitle.parameters;
+ &no.function.parameters;
+
+
+
+ &reftitle.returnvalues;
+
+ An array of ReflectionMethod objects keyed by the hook they are for.
+ For example, a property with both get and set hooks will return
+ a 2 element array with string keys get and set,
+ each of which are a ReflectionMethod object.
+ The order in which they are returned is explicitly undefined.
+ If no hooks are defined, an empty array is returned.
+
+
+
+
+ &reftitle.examples;
+
+ ReflectionProperty::getHooks example
+
+ "Name here"; }
+
+ public int $count;
+}
+
+$rClass = new \ReflectionClass(Example::class);
+
+$rProp = $rClass->getProperty('name');
+var_dump($rProp->getHooks());
+
+$rProp = $rClass->getProperty('count');
+var_dump($rProp->getHooks());
+?>
+]]>
+
+
+
+
+
+ &reftitle.seealso;
+
+ ReflectionMethod
+ ReflectionProperty::hasHooks
+
+
+
+
+
diff --git a/reference/reflection/reflectionproperty/getrawvalue.xml b/reference/reflection/reflectionproperty/getrawvalue.xml
new file mode 100644
index 000000000000..bbec5fd539c7
--- /dev/null
+++ b/reference/reflection/reflectionproperty/getrawvalue.xml
@@ -0,0 +1,108 @@
+
+
+
+ ReflectionProperty::getRawValue
+ Returns the value of a property, bypassing a get hook if defined
+
+
+
+ &reftitle.description;
+
+ publicmixedReflectionProperty::getRawValue
+ objectobject
+
+ &warn.undocumented.func;
+
+ Returns the value of a property, bypassing a get hook if defined.
+
+
+
+
+ &reftitle.parameters;
+
+
+ object
+
+
+ The object from which to retrieve a value.
+
+
+
+
+
+
+
+ &reftitle.returnvalues;
+
+ The stored value of the property, bypassing a get hook if defined.
+
+
+
+
+ &reftitle.errors;
+
+ If the property is virtual, an Error will be thrown,
+ as there is no raw value to retrieve.
+
+
+
+
+ &reftitle.examples;
+
+ ReflectionProperty::getRawValue example
+
+ strtolower($this->tag);
+ }
+}
+
+$example = new Example();
+$example->tag = 'PHP';
+
+$rClass = new \ReflectionClass(Example::class);
+$rProp = $rClass->getProperty('tag');
+
+// These would go through the get hook, so would produce "php".
+print $example->tag;
+print $rProp->getValue($example);
+
+// But this would bypass the hook and produce "PHP".
+print $rProp->setRawValue($example);
+?>
+]]>
+
+
+
+
+
+ &reftitle.seealso;
+
+ Asymmetric property visibility
+
+
+
+
+
diff --git a/reference/reflection/reflectionproperty/getsettabletype.xml b/reference/reflection/reflectionproperty/getsettabletype.xml
new file mode 100644
index 000000000000..da625a7d717c
--- /dev/null
+++ b/reference/reflection/reflectionproperty/getsettabletype.xml
@@ -0,0 +1,111 @@
+
+
+
+ ReflectionProperty::getSettableType
+ Returns the parameter type of a setter hook
+
+
+
+ &reftitle.description;
+
+ publicReflectionTypenullReflectionProperty::getSettableType
+
+
+
+ Returns the parameter type of a set hook.
+ If no set hook is defined, it behaves identically
+ to ReflectionProperty::getType.
+
+
+
+
+ &reftitle.parameters;
+ &no.function.parameters;
+
+
+
+ &reftitle.returnvalues;
+
+
+ This method returns an instance of ReflectionType that matches
+ the settable type for the property.
+
+
+ If there is a set hook that defines an explicit type, that will be returned.
+
+
+ If the hook does not specify a type, or it does not exist, the property type will be
+ returned, identically to ReflectionProperty::getType. This value may be &null;
+ if the property is untyped.
+
+
+ If the property is virtual and has no set hook, a ReflectionType
+ instance for never will be returned.
+
+
+
+
+
+ &reftitle.examples;
+
+ ReflectionProperty::getSettableType example
+
+ strtolower($value);
+ }
+
+ public string $wider {
+ set(string|Stringable $value) => (string)$value;
+ }
+
+ public string $virtual {
+ get => 'Do not change this';
+ }
+
+ public $untyped = 'silly';
+}
+
+$rClass = new \ReflectionClass(Example::class);
+
+var_dump($rClass->getProperty('basic')->getSettableType());
+var_dump($rClass->getProperty('wider')->getSettableType());
+var_dump($rClass->getProperty('virtual')->getSettableType());
+var_dump($rClass->getProperty('untyped')->getSettableType());
+?>
+]]>
+
+
+
+
+
+ &reftitle.seealso;
+
+ ReflectionProperty::getType
+
+
+
+
+
diff --git a/reference/reflection/reflectionproperty/hashook.xml b/reference/reflection/reflectionproperty/hashook.xml
new file mode 100644
index 000000000000..ed2ee56c3d22
--- /dev/null
+++ b/reference/reflection/reflectionproperty/hashook.xml
@@ -0,0 +1,90 @@
+
+
+
+ ReflectionProperty::hasHook
+ Returns whether the property has a given hook defined.
+
+
+
+ &reftitle.description;
+
+ publicboolReflectionProperty::hasHook
+ PropertyHookTypetype
+
+
+ Returns whether the property has a given hook defined.
+
+
+
+
+ &reftitle.parameters;
+
+
+ PropertyHookType
+
+
+ The type of hook to check for.
+
+
+
+
+
+
+
+ &reftitle.returnvalues;
+
+ Returns &true; if the hook is defined on this property, &false; if not.
+
+
+
+
+ &reftitle.examples;
+
+ ReflectionProperty::hasHook example
+
+ "Name here"; }
+}
+
+$rClass = new \ReflectionClass(Example::class);
+$rProp = $rClass->getProperty('name');
+var_dump($rProp->hasHook(PropertyHookType::Get));
+var_dump($rProp->hasHook(PropertyHookType::Set));
+?>
+]]>
+
+
+
+
+
+ &reftitle.seealso;
+
+ ReflectionMethod
+ PropertyHookType
+
+
+
+
+
diff --git a/reference/reflection/reflectionproperty/hashooks.xml b/reference/reflection/reflectionproperty/hashooks.xml
new file mode 100644
index 000000000000..0fbb37f42bda
--- /dev/null
+++ b/reference/reflection/reflectionproperty/hashooks.xml
@@ -0,0 +1,92 @@
+
+
+
+ ReflectionProperty::hasHooks
+ Returns whether the property has any hooks defined
+
+
+
+ &reftitle.description;
+
+ publicboolReflectionProperty::hasHooks
+
+
+ &warn.undocumented.func;
+
+ Returns whether the property has any hooks defined.
+
+
+
+
+ &reftitle.parameters;
+ &no.function.parameters;
+
+
+
+ &reftitle.returnvalues;
+
+ Returns &true; if the property has at least one hook defined, &false; otherwise.
+
+
+
+
+ &reftitle.examples;
+
+ ReflectionProperty::hasHooks example
+
+ "Name here"; }
+
+ public string $none;
+}
+
+$rClass = new \ReflectionClass(Example::class);
+var_dump($rClass->getProperty('name')->hasHooks());
+var_dump($rClass->getProperty('none')->hasHooks());
+?>
+]]>
+
+
+
+
+
+ &reftitle.notes;
+
+
+ This method is equivalent to checking ReflectionProperty::getHooks
+ against an empty array.
+
+
+
+
+
+ &reftitle.seealso;
+
+ ReflectionProperty::getHooks
+
+
+
+
+
diff --git a/reference/reflection/reflectionproperty/isabstract.xml b/reference/reflection/reflectionproperty/isabstract.xml
new file mode 100644
index 000000000000..b0073a0cad62
--- /dev/null
+++ b/reference/reflection/reflectionproperty/isabstract.xml
@@ -0,0 +1,59 @@
+
+
+
+ ReflectionProperty::isAbstract
+ Determines if a property is abstract
+
+
+
+ &reftitle.description;
+
+ publicboolReflectionProperty::isAbstract
+
+
+
+ Determines if a property is
+ abstract.
+
+
+
+
+ &reftitle.parameters;
+ &no.function.parameters;
+
+
+
+ &reftitle.returnvalues;
+
+ Returns &true; if the property is marked abstract, &false; otherwise.
+
+
+
+
+ &reftitle.seealso;
+
+ Abstract properties
+
+
+
+
+
diff --git a/reference/reflection/reflectionproperty/isfinal.xml b/reference/reflection/reflectionproperty/isfinal.xml
new file mode 100644
index 000000000000..d4612b7fd781
--- /dev/null
+++ b/reference/reflection/reflectionproperty/isfinal.xml
@@ -0,0 +1,92 @@
+
+
+
+ ReflectionProperty::isFinal
+ Determines if this property is final or not
+
+
+
+ &reftitle.description;
+
+ publicboolReflectionProperty::isFinal
+
+
+ &warn.undocumented.func;
+
+ Returns whether the property is
+ final.
+ If the property is marked private(set),
+ then it will also be implicitly final.
+
+
+
+
+ &reftitle.parameters;
+ &no.function.parameters;
+
+
+
+ &reftitle.returnvalues;
+
+ Returns &true; if the property is explicitly marked final,
+ or if it is implicitly final due to being private(set).
+ Returns &false; otherwise.
+
+
+
+
+ &reftitle.examples;
+
+ ReflectionProperty::isFinal example
+
+getProperty('name')->isFinal());
+var_dump($rClass->getProperty('age')->isFinal());
+var_dump($rClass->getProperty('job')->isFinal());
+?>
+]]>
+
+
+
+
+
+ &reftitle.seealso;
+
+ final class elements
+ Asymmetric property visibility
+
+
+
+
+
diff --git a/reference/reflection/reflectionproperty/isprivateset.xml b/reference/reflection/reflectionproperty/isprivateset.xml
new file mode 100644
index 000000000000..0a9481ac8c7f
--- /dev/null
+++ b/reference/reflection/reflectionproperty/isprivateset.xml
@@ -0,0 +1,63 @@
+
+
+
+ ReflectionProperty::isPrivateSet
+ Checks if property is private for writing
+
+
+
+ &reftitle.description;
+
+ publicboolReflectionProperty::isPrivateSet
+
+
+
+ Checks whether the property is private for writing.
+
+
+
+
+ &reftitle.parameters;
+ &no.function.parameters;
+
+
+
+ &reftitle.returnvalues;
+
+ &true; if the property is private(set), &false; otherwise.
+
+
+
+
+ &reftitle.seealso;
+
+ ReflectionProperty::isPublic
+ ReflectionProperty::isProtected
+ ReflectionProperty::isProtectedSet
+ ReflectionProperty::isPrivate
+ ReflectionProperty::isReadOnly
+ ReflectionProperty::isStatic
+
+
+
+
+
diff --git a/reference/reflection/reflectionproperty/isprotectedset.xml b/reference/reflection/reflectionproperty/isprotectedset.xml
new file mode 100644
index 000000000000..d9178058ab67
--- /dev/null
+++ b/reference/reflection/reflectionproperty/isprotectedset.xml
@@ -0,0 +1,63 @@
+
+
+
+ ReflectionProperty::isProtectedSet
+ Checks whether the property is protected for writing
+
+
+
+ &reftitle.description;
+
+ publicboolReflectionProperty::isProtectedSet
+
+
+
+ Checks whether the property is protected for writing.
+
+
+
+
+ &reftitle.parameters;
+ &no.function.parameters;
+
+
+
+ &reftitle.returnvalues;
+
+ &true; if the property is protected(set), &false; otherwise.
+
+
+
+
+ &reftitle.seealso;
+
+ ReflectionProperty::isPublic
+ ReflectionProperty::isProtected
+ ReflectionProperty::isPrivate
+ ReflectionProperty::isPrivateSet
+ ReflectionProperty::isReadOnly
+ ReflectionProperty::isStatic
+
+
+
+
+
diff --git a/reference/reflection/reflectionproperty/ispublic.xml b/reference/reflection/reflectionproperty/ispublic.xml
index 85221d0f0f0f..ebc642ce0386 100644
--- a/reference/reflection/reflectionproperty/ispublic.xml
+++ b/reference/reflection/reflectionproperty/ispublic.xml
@@ -34,12 +34,29 @@
+
+ &reftitle.notes;
+
+
+ Be aware that a property being public does not always
+ imply is it publicly writeable. A property could be virtual with no
+ set hook, or it could be readonly
+ and already have been written to, or it could have a
+ set
+ visibility defined that is non-public. In all of those cases,
+ this method will return &true; but the property will not be writeable.
+
+
+
+
&reftitle.seealso;
ReflectionProperty::isProtected
+ ReflectionProperty::isProtectedSetReflectionProperty::isPrivate
+ ReflectionProperty::isPrivateSetReflectionProperty::isReadOnlyReflectionProperty::isStatic
diff --git a/reference/reflection/reflectionproperty/isvirtual.xml b/reference/reflection/reflectionproperty/isvirtual.xml
new file mode 100644
index 000000000000..401663a6d859
--- /dev/null
+++ b/reference/reflection/reflectionproperty/isvirtual.xml
@@ -0,0 +1,97 @@
+
+
+
+ ReflectionProperty::isVirtual
+ Determines if a property is virtual
+
+
+
+ &reftitle.description;
+
+ publicboolReflectionProperty::isVirtual
+
+
+
+ Determines if a property is virtual.
+
+
+
+
+ &reftitle.parameters;
+ &no.function.parameters;
+
+
+
+ &reftitle.returnvalues;
+
+ Returns &true; if the property is virtual, &false; otherwise.
+
+
+
+
+ &reftitle.examples;
+
+ ReflectionProperty::isVirtual example
+
+ "Name here"; }
+
+ // This hook references the property by name,
+ // so it is not virtual.
+ public int $age {
+ set {
+ if ($value <= 0) {
+ throw new \InvalidArgumentException();
+ }
+ $this->age = $value;
+ }
+ }
+
+ // Non-hooked properties are always not-virtual.
+ public string $job;
+}
+
+$rClass = new \ReflectionClass(Example::class);
+
+var_dump($rClass->getProperty('name')->isVirtual());
+var_dump($rClass->getProperty('age')->isVirtual());
+var_dump($rClass->getProperty('job')->isVirtual());
+?>
+]]>
+
+
+
+
+
+ &reftitle.seealso;
+
+ Virtual properties
+
+
+
+
+
diff --git a/reference/reflection/reflectionproperty/setrawvalue.xml b/reference/reflection/reflectionproperty/setrawvalue.xml
new file mode 100644
index 000000000000..071f967488dc
--- /dev/null
+++ b/reference/reflection/reflectionproperty/setrawvalue.xml
@@ -0,0 +1,120 @@
+
+
+
+ ReflectionProperty::setRawValue
+ Sets the value of a property, bypassing a set hook if defined
+
+
+
+ &reftitle.description;
+
+ publicvoidReflectionProperty::setRawValue
+ objectobject
+ mixedvalue
+
+
+ Sets the value of a property, bypassing a set hook if defined.
+
+
+
+
+ &reftitle.parameters;
+
+
+ object
+
+
+ The object on which to set the property value.
+
+
+
+
+ value
+
+
+ The value to write. It must still be valid according to the property's type.
+
+
+
+
+
+
+
+ &reftitle.returnvalues;
+
+ &return.void;
+
+
+
+
+ &reftitle.errors;
+
+ If the property is virtual, an Error will be thrown,
+ as there is no raw value to set.
+
+
+
+
+ &reftitle.examples;
+
+ ReflectionProperty::setRawValue example
+
+age = $value;
+ }
+ }
+}
+
+$example = new Example();
+
+$rClass = new \ReflectionClass(Example::class);
+$rProp = $rClass->getProperty('age');
+
+// These would go through the set hook, and throw an exception.
+$example->age = -2;
+$rProp->setValue($example, -2);
+
+// But this would set the $age to -2 without error.
+$rProp->setRawValue($example, -2);
+?>
+]]>
+
+
+
+
+
+ &reftitle.seealso;
+
+ Asymmetric property visibility
+
+
+
+
+
diff --git a/reference/reflection/versions.xml b/reference/reflection/versions.xml
index fc4b5fe39158..fe4367559da4 100644
--- a/reference/reflection/versions.xml
+++ b/reference/reflection/versions.xml
@@ -345,6 +345,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+