Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2894304
xsprintf.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
4 KB
Referenced Files
None
Subscribers
None
xsprintf.php
View Options
<?php
/**
* Parse a `sprintf()`-style format string in an extensible way.
*
* This method allows you to build a function with `sprintf()` semantics but
* custom conversions for different datatypes. Three examples are
* @{function:jsprintf} (which builds JavaScript strings),
* @{function:qsprintf} (which builds MySQL strings), and
* @{function:csprintf} (which builds command line strings).
*
* To build a new `xsprintf`-family function, provide a callback which conforms
* to the specification described in @{function:xsprintf_callback_example}. The
* callback will be invoked each time a conversion (like "%Z") is encountered
* in the string. For instance, if you call `xsprintf()` like this...
*
* $result = xsprintf(
* 'xsprintf_callback_example',
* $userdata = null,
* array(
* 'The %M is made of %C.',
* 'moon',
* 'cheese',
* ));
*
* ...the callback will be invoked twice, at string positions 5 ("M") and 19
* ("C"), with values "moon" and "cheese" respectively.
*
* @param string $callback The name of a callback to pass conversions to.
* @param wild $userdata Optional userdata to pass to the callback. For
* @{function:qsprintf}, this is the database connection.
* @param list $argv List of arguments, with the `sprintf()` pattern in
* position 0.
* @return string Formatted string.
*/
function
xsprintf
(
$callback
,
$userdata
,
array
$argv
)
{
$argc
=
count
(
$argv
)
;
$arg
=
0
;
$pos
=
0
;
$pattern
=
$argv
[
0
]
;
$len
=
strlen
(
$pattern
)
;
$conv
=
false
;
// Are we inside a conversion?
for
(
$pos
=
0
;
$pos
<
$len
;
$pos
++
)
{
$c
=
$pattern
[
$pos
]
;
if
(
$conv
)
{
// We could make a greater effort to support formatting modifiers,
// but they really have no place in semantic string formatting.
if
(
strpos
(
"'-0123456789.\$+"
,
$c
)
!==
false
)
{
throw
new
InvalidArgumentException
(
pht
(
'%s does not support the "%s" modifier.'
,
'xsprintf()'
,
"%{$c}"
)
)
;
}
if
(
$c
!==
'%'
)
{
$conv
=
false
;
$arg
++
;
if
(
$arg
>=
$argc
)
{
throw
new
BadFunctionCallException
(
pht
(
'Too few arguments to %s.'
,
'xsprintf()'
)
)
;
}
if
(
$callback
!==
null
)
{
// See T13588 and D21500. This function uses "$callback()", instead
// of "call_user_func()", to simplify reference behavior: some of
// these arguments must be passed by reference.
// Prior to PHP7, this syntax will not work if "$callback" is a
// string referencing a static method, like "C::m".
// This syntax does work if "$callback" is an array referencing
// a static method, like "array('C', 'm')", in all versions of PHP
// since PHP 5.4.
$callback
(
$userdata
,
$pattern
,
$pos
,
$argv
[
$arg
]
,
$len
)
;
}
}
}
if
(
$c
===
'%'
)
{
// If we have "%%", this encodes a literal percentage symbol, so we are
// no longer inside a conversion.
$conv
=
!
$conv
;
}
}
if
(
$arg
!==
(
$argc
-
1
)
)
{
throw
new
BadFunctionCallException
(
pht
(
'Too many arguments to %s.'
,
'xsprintf()'
)
)
;
}
$argv
[
0
]
=
$pattern
;
return
call_user_func_array
(
'sprintf'
,
$argv
)
;
}
/**
* Example @{function:xsprintf} callback. When you call `xsprintf`, you must
* pass a callback like this one. `xsprintf` will invoke the callback when it
* encounters a conversion (like "%Z") in the pattern string.
*
* Generally, this callback should examine `$pattern[$pos]` (which will contain
* the conversion character, like 'Z'), escape `$value` appropriately, and then
* replace `$pattern[$pos]` with an 's' so `sprintf` prints the escaped value
* as a string. However, more sophisticated behaviors are possible --
* particularly, consuming multiple characters to allow for conversions like
* "%Ld". In this case, the callback needs to `substr_replace` the entire
* conversion with 's' and then update `$length`.
*
* For example implementations, see @{function:xsprintf_command},
* @{function:xsprintf_javascript} and @{function:xsprintf_query}.
*
* @param wild $userdata Arbitrary, optional userdata. This is whatever
* userdata was passed to @{function:xsprintf}.
* @param string &$pattern The pattern string being parsed.
* @param int &$pos The current character position in the string.
* @param wild &$value The value to convert.
* @param int &$length The string length.
*/
function
xsprintf_callback_example
(
$userdata
,
&
$pattern
,
&
$pos
,
&
$value
,
&
$length
)
{
throw
new
RuntimeException
(
pht
(
'This function exists only to document the call signature '
.
'for %s callbacks.'
,
'xsprintf()'
)
)
;
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sun, Jan 19, 19:42 (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1115422
Default Alt Text
xsprintf.php (4 KB)
Attached To
Mode
rARC Arcanist
Attached
Detach File
Event Timeline
Log In to Comment