Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions language/predefined/attributes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
&language.predefined.attributes.attribute;
&language.predefined.attributes.allowdynamicproperties;
&language.predefined.attributes.deprecated;
&language.predefined.attributes.nodiscard;
&language.predefined.attributes.override;
&language.predefined.attributes.returntypewillchange;
&language.predefined.attributes.sensitiveparameter;
Expand Down
160 changes: 160 additions & 0 deletions language/predefined/attributes/nodiscard.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<reference xml:id="class.nodiscard" role="class" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude">
<title>The NoDiscard attribute</title>
<titleabbrev>NoDiscard</titleabbrev>

<partintro>

<section xml:id="nodiscard.intro">
&reftitle.intro;
<simpara>
This attribute can be used to indicate that the return value of a function
or a method should not be discarded. If the return value is not used in any
way, a warning will be emitted.
</simpara>
<simpara>
This is useful for functions where not checking the return value is likely
to be a bug.
</simpara>
<simpara>
To intentionally discard the return value of such a function, use (void)
cast to suppress the warning.
</simpara>
</section>

<section xml:id="nodiscard.synopsis">
&reftitle.classsynopsis;

<classsynopsis class="class">
<ooclass>
<modifier>final</modifier>
<classname>NoDiscard</classname>
</ooclass>

<classsynopsisinfo role="comment">&Properties;</classsynopsisinfo>
<fieldsynopsis>
<modifier>public</modifier>
<modifier>readonly</modifier>
<type class="union"><type>string</type><type>null</type></type>
<varname linkend="nodiscard.props.message">message</varname>
</fieldsynopsis>

<classsynopsisinfo role="comment">&Methods;</classsynopsisinfo>
<xi:include xpointer="xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.nodiscard')/db:refentry/db:refsect1[@role='description']/descendant::db:constructorsynopsis[@role='NoDiscard'])">
<xi:fallback/>
</xi:include>
</classsynopsis>

</section>

<section xml:id="nodiscard.props">
&reftitle.properties;
<variablelist>
<varlistentry xml:id="nodiscard.props.message">
<term><varname>message</varname></term>
<listitem>
<para>
An optional message explaining why the return value should not be discarded.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>

<section>
&reftitle.examples;
<example>
<title>Basic usage</title>
<programlisting role="php">
<![CDATA[
<?php

/**
* Processes all the given items and returns an array with the results of the
* operation for each item. `null` indicates success and an Exception indicates
* an error. The keys of the result array match the keys of the $items array.
*
* @param array<string> $items
* @return array<null|Exception>
*/
#[\NoDiscard("as processing might fail for individual items")]
function bulk_process(array $items): array {
$results = [];

foreach ($items as $key => $item) {
if (\random_int(0, 9999) < 9999) {
// Pretend to do something useful with $item,
// which will succeed in 99.99% of cases.
echo "Processing {$item}", PHP_EOL;
$error = null;
} else {
$error = new \Exception("Failed to process {$item}.");
}

$results[$key] = $error;
}

return $results;
}

?>
]]>
</programlisting>
&example.outputs.85.similar;
<screen>
<![CDATA[
Warning: The return value of function bulk_process() should either be used or intentionally ignored by casting it as (void), as processing might fail for individual items
]]>
</screen>
</example>
<example>
<title>Intentionally discarding the return value</title>
<programlisting role="php">
<![CDATA[
<?php

#[\NoDiscard]
function some_command(): int {
return 1;
}

(void) some_command();

?>
]]>
</programlisting>
</example>
</section>

<section xml:id="nodiscard.seealso">
&reftitle.seealso;
<simplelist>
<member><link linkend="language.attributes">Attributes overview</link></member>
</simplelist>
</section>

</partintro>

&language.predefined.attributes.nodiscard.construct;

</reference>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
53 changes: 53 additions & 0 deletions language/predefined/attributes/nodiscard/construct.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xml:id="nodiscard.construct" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>NoDiscard::__construct</refname>
<refpurpose>Construct a new NoDiscard attribute instance</refpurpose>
</refnamediv>

<refsect1 role="description">
&reftitle.description;
<constructorsynopsis role="NoDiscard">
<modifier>public</modifier> <methodname>NoDiscard::__construct</methodname>
<methodparam choice="opt"><type class="union"><type>string</type><type>null</type></type><parameter>message</parameter><initializer>&null;</initializer></methodparam>
</constructorsynopsis>
<simpara>
Constructs a new <classname>NoDiscard</classname> instance.
</simpara>
</refsect1>

<refsect1 role="parameters">
&reftitle.parameters;
<variablelist>
<varlistentry>
<term><parameter>message</parameter></term>
<listitem>
<para>
The value of the <property linkend="nodiscard.props.message">message</property> property.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
2 changes: 2 additions & 0 deletions language/predefined/versions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@
<function name="Override::__construct" from="PHP 8 &gt;= 8.3.0"/>
<function name="Deprecated" from="PHP 8 &gt;= 8.4.0"/>
<function name="Deprecated::__construct" from="PHP 8 &gt;= 8.4.0"/>
<function name="NoDiscard" from="PHP 8 &gt;= 8.5.0"/>
<function name="NoDiscard::__construct" from="PHP 8 &gt;= 8.5.0"/>
<function name="__PHP_Incomplete_Class" from="PHP 4 &gt;=4.0.1, PHP 5, PHP 7, PHP 8"/>
</versions>
<!-- Keep this comment at the end of the file
Expand Down