Main interface to the PHP client API.
This module provides an object-oriented interface to Helix Core, the Perforce version control system. Data is returned in arrays and input can also be supplied in these formats.
Each P4
object represents a connection to the Helix server, and multiple commands may be executed (serially) over a single
connection (which of itself can result in substantially improved
performance if executing long sequences of
Helix Core
commands).
P4
object.Specify your Helix Core client environment:
client
host
password
port
user
Set any options to control output or error handling:
exception_level
Connect to the Perforce service.
The Helix Core protocol is not designed to support multiple concurrent queries over the same connection. Multithreaded applications that use the C++ API or derived APIs (including P4PHP) should ensure that a separate connection is used for each thread, or that only one thread may use a shared connection at a time.
Contains the API compatibility level desired. This is useful when
writing scripts using
Helix Core
commands that do not yet support tagged output. In these cases, upgrading
to a later server that supports tagged output for the commands in
question can break your script. Using this method allows you to lock your
script to the output format of an older
Helix Core
release and facilitate seamless upgrades. Must be called before calling
P4::connect()
.
<?php
$p4 = new P4();
$p4->api_level = 57; // Lock to 2005.1 format
$p4->connect();
...
$p4->disconnect();
?>
For the API integer levels that correspond to each Helix Core release, see:
http://kb.perforce.com/article/512
Contains the character set to use when connect to a Unicode enabled
server. Do not use when working with non-Unicode-enabled servers. By
default, the character set is the value of the P4CHARSET
environment variable. If the character set is invalid, this method raises
a P4_Exception
.
<?php
$p4 = new P4();
$p4->client = "www";
$p4->charset = "iso8859-1";
$p4->connect();
$p4->run_sync();
$p4->disconnect();
?>
Contains the name of your client workspace. By default, this is the
value of the P4CLIENT
taken from any P4CONFIG
file present, or from the environment according to the normal
Helix Core
conventions.
Contains the current working directly. Can be called prior to executing
any
Helix Core
command. Sometimes necessary if your script executes a
chdir()
as part of its processing.
<?php
$p4 = new P4();
$p4->cwd = "/home/bruno"
?>
Returns an array containing the error messages received during execution of the last command.
<?php
$p4 = new P4();
$p4->connect();
$p4->exception_level = 1;
$p4->connect(); // P4_Exception on failure
$p4->run_sync(); // File(s) up-to-date is a warning; no exception raised
$err = $p4->errors;
print_r( $err );
$p4->disconnect();
?>
Configures the events which give rise to exceptions. The following three levels are supported:
0
: disables all exception handling and makes the
interface completely procedural; you are responsible for checking the
P4::errors
and P4::warnings
arrays.1
: causes exceptions to be raised only when errors are
encountered.2
: causes exceptions to be raised for both errors and
warnings. This is the default.For example:
<?php
$p4 = new P4();
$p4->exception_level = 1;
$p4->connect(); // P4_Exception on failure
$p4->run_sync(); // File(s) up-to-date is a warning; no exception raised
$p4->disconnect();
?>
Controls whether keys with trailing numbers are expanded into arrays
when using tagged output. By default, expand_sequences
is
true
to maintain backwards compatibility. Expansion can be
enabled and disabled on a per-command basis.
For example:
<?php
$p4 = new P4();
$p4->connect();
$p4->expand_sequences = false; // disables sequence expansion.
$result = $p4->run( 'fstat', '-Oa', '//depot/path/...' );
var_dump( $result );
?>
Contains the output handler.
Contains the name of the current host. It defaults to the value of
P4HOST
taken from any P4CONFIG
file present, or
from the environment as per the usual
Helix Core
convention. Must be called before connecting to the Helix server.
<?php
$p4 = new P4();
$p4->host = "workstation123.perforce.com";
$p4->connect();
?>
Contains input for the next command.
Set this property prior to running a command that requires input from
the user. When the command requests input, the specified data is supplied
to the command. Typically, commands of the form p4 cmd
-i
are invoked using the
P4::save_<spectype>()
methods, which retrieve
the value from P4::input
internally; there is no need
to set P4::input
when using the
P4::save_<spectype>()
shortcuts.
You may pass a string, an array, or (for commands that take multiple inputs from the user) an array of strings or arrays. If you pass an array, note that the first element of the array will be popped each time Helix Core asks the user for input.
For example, the following code supplies a description for the default changelist and then submits it to the depot:
<?php
$p4 = new P4();
$p4->connect();
$change = $p4->run_change( "-o" )[0];
$change[ 'Description' ] = "Autosubmitted changelist";
$p4->input = $change;
$p4->run_submit( "-i" );
$p4->disconnect();
?>
Limit the amount of time (in milliseconds) spent during data scans to
prevent the server from locking tables for too long. Commands that take
longer than the limit will be aborted. The limit remains in force until
you disable it by setting it to zero. See p4 help
maxlocktime
for information on the commands that support
this limit.
Limit the number of results
Helix Core
permits for subsequent commands. Commands that produce more than this
number of results will be aborted. The limit remains in force until you
disable it by setting it to zero. See p4 help
maxresults
for information on the commands that support
this limit.
Limit the number of database records
Helix Core
scans for subsequent commands. Commands that attempt to scan more than
this number of records will be aborted. The limit remains in force until
you disable it by setting it to zero. See p4 help
maxscanrows
for information on the commands that support
this limit.
Contains the name of the current P4CONFIG
file, if any.
This property cannot be set.
Contains your
Helix Core
password or login ticket. If not used, takes the value of
P4PASSWD
from any P4CONFIG
file in effect, or
from the environment according to the normal
Helix Core
conventions.
This password is also used if you later call
P4::run_login()
to log in using the 2003.2 and later ticket
system. After running P4::run_login()
, the property contains
the ticket the allocated by the server.
<?php
$p4 = new P4();
$p4->password = "mypass";
$p4->connect();
$p4->run_login();
...
$p4->disconnect();
?>
Contains the host and port of the Helix server to which you want to connect. It defaults to the value of
P4PORT
in any P4CONFIG
file in effect, and then
to the value of P4PORT
taken from the environment.
<?php
$p4 = new P4();
$p4->port = "localhost:1666";
$p4->connect();
...
$p4->disconnect();
?>
Contains the name of the program, as reported to
Helix Core
system administrators running p4 monitor show -e
. The
default is unnamed p4-php script
<?php
$p4 = new P4();
$p4->prog = "sync-script";
print $p4->prog;
$p4->connect();
...
$p4->disconnect();
?>
Returns the current Helix serverlevel. Each iteration of the Helix server is given a level number. As part of the initial communication this value is passed between the client application and the Helix server. This value is used to determine the communication that the Helix server will understand. All subsequent requests can therefore be tailored to meet the requirements of this server level.
This property is 0 before the first command is run, and is set automatically after the first communication with the server.
For the API integer levels that correspond to each Helix Core release, see:
http://kb.perforce.com/article/571
If true
, P4::streams
enables support
for streams. By default, streams support is enabled at 2011.1 or higher
(api_level
>= 70). Raises a
P4Exception
if you attempt to enable streams on a
pre-2011.1 server. You can enable or disable support for streams both
before and after connecting to the server.
<?php
$p4 = new P4();
$p4->streams = false;
print $p4->streams;
?>
If true
, P4::tagged
enables tagged
output. By default, tagged output is on.
<?php
$p4 = new P4();
$p4->tagged = false;
print $p4->tagged;
?>
Contains the location of the P4TICKETS
file.
Contains the
Helix Core
username. It defaults to the value of P4USER
taken from any
P4CONFIG
file present, or from the environment as per the
usual
Helix Core
convention.
<?php
$p4 = new P4();
$p4->user = "bruno";
$p4->connect();
...
P4::disconnect();
?>
Contains the version of the program, as reported to Helix Core system administrators in the server log.
<?php
$p4 = new P4();
$p4->version = "123";
print $p4->version;
$p4->connect();
...
$p4->disconnect();
?>
Contains the array of warnings that arose during execution of the last command.
<?php
$p4 = new P4();
$p4->connect(); // P4_Exception on failure
$p4->exception_level = 2;
$files = $p4->run_sync();
$warn = $p4->warnings;
print_r( $warn );
$p4->disconnect();
?>
Construct a new P4
object. For example:
<?php
$p4 = new P4();
?>
Return the version of P4PHP that you are using, and, if applicable, the version of the OpenSSL library used for building the underlying Helix C/C++ API with which P4PHP was built).
<?php
print P4::identify();
?>
produces output similar to the following:
Perforce - The Fast Software Configuration Management System. Copyright 1995-2013 Perforce Software. All rights reserved. Rev. P4PHP/LINUX26X86/2013.1/644389 (2013.1 API) (2013/05/21).
Initializes the Helix Core client and connects to the server.
If the connection is successfully established, returns
None
. If the connection fails and
exception_level
is 0
, returns False,
otherwise raises a P4_Exception
. If already
connected, prints a message.
<?php
$p4 = new P4();
$p4->connect();
...
$p4->disconnect();
?>
Returns true
if connected to the Helix server and the connection is alive, otherwise false
.
<?php
$p4 = new P4();
if ( !$p4->connected() ) {
print "Not Connected\n";
}
$p4->connect();
if ( $p4->connected() ) {
print "Connected\n";
}
$p4->disconnect();
?>
The delete_<spectype>()
methods are shortcut
methods that allow you to delete the definitions of clients, labels,
branches, etc. These methods are equivalent to:
P4::run( "<spectype>", '-d', [options], "spec name" );
The following code uses P4::delete_client()
to delete
client workspaces that have not been accessed in more than 365 days:
<?php
$p4 = new P4();
try {
$p4->connect();
foreach ( $p4->run_clients() as $client) {
$atime = int( $client['Access'] );
// If the client has not been accessed for a year, delete it
if ( (time() - $atime) > 31536000 ) { // seconds in 365 days
$p4->delete_client( "-f", $client["Client"] );
}
}
} catch ( P4_Exception $e ) {
print $e->getMessage() . "\n";
foreach ( $p4->errors as $error ) {
print "Error: $error\n";
}
}
?>
Disconnect from the Helix server. Call this method before exiting your script.
<?php
$p4 = new P4();
$p4->connect();
...
$p4->disconnect();
?>
Get the value of a
Helix Core
environment variable, taking into account P4CONFIG
files and
(on Windows or OS X) the registry or user preferences.
<?php
$p4 = new P4();
print $p4->env( "P4PORT" );
?>
The fetch_<spectype>()
methods are shortcuts
for running $p4->run( "<spectype>", "-o")
and returning the first element of the array. For example:
$label = $p4->fetch_label( "labelname" );
$change = $p4->fetch_change( changeno);
$clientspec = $p4->fetch_client( "clientname" );
are equivalent to:
$label = $p4->run( "label", "-o", "labelname" );
$change = $p4->run( "change", "-o", changeno );
$clientspec = $p4->run( "client", "-o", clientname );
Converts the fields in the array containing the elements of a Helix server form (spec) into the string representation familiar to users. The first argument is the type of spec to format: for example, client, branch, label, and so on. The second argument is the hash to parse.
There are shortcuts available for this method. You can use
$p4->format_<spectype>( array)
instead of
$p4->format_spec( "<spectype>", array )
,
where <spectype> is the name of a
Helix server
spec, such as client, label, etc.
The format_<spectype>()
methods are shortcut
methods that allow you to quickly fetch the definitions of clients,
labels, branches, etc. They’re equivalent to:
$p4->format_spec( "<spectype>", array );
Parses a
Helix server
form (spec) in text form into an array using the spec definition obtained
from the server. The first argument is the type of spec to parse:
client
, branch
, label
, and so on.
The second argument is the string buffer to parse.
There are shortcuts available for this method. You can use:
$p4->parse_<spectype>( buf );
instead of:
$p4->parse_spec( "<spectype>", buf );
where <spectype> is one of client
,
branch
, label
, and so on.
This is equivalent to:
$p4->parse_spec( "<spectype>", string )
For example:
$p4->parse_job( myJob );
converts the String representation of a job spec into an array.
To parse a spec, P4
needs to have the spec
available. When not connected to the Helix server, P4
assumes the default format for the spec,
which is hardcoded. This assumption can fail for jobs if the server’s
jobspec has been modified. In this case, your script can load a job from
the server first with the command fetch_job(
"somename")
, andP4 will cache and use the spec format in
subsequent P4::parse_job()
calls.
Base interface to all the run methods in this API. Runs the specified Helix Core command with the arguments supplied. Arguments may be in any form as long as they can be converted to strings. However, each command's options should be passed as quoted and comma-separated strings, with no leading space. For example:
p4::run("print","-o","test-print","-q","//depot/Jam/MAIN/src/expand.c")
Failing to pass options in this way can result in confusing error messages.
The P4::run()
method returns an array of results whether
the command succeeds or fails; the array may, however, be empty. Whether
the elements of the array are strings or arrays depends on:
$p4->tagged =
false
.In the event of errors or warnings, and depending on the exception level
in force at the time, P4::run()
raises a
P4_Exception
. If the current exception level is below
the threshold for the error/warning, P4::run()
returns the
output as normal and the caller must explicitly review
P4::errors
and P4::warnings
to
check for errors or warnings.
<?php
$p4 = new P4();
print $p4->env( "P4PORT" );
$p4->connect();
$spec = $p4->run( "client", "-o" )[0];
$p4->disconnect();
?>
Shortcuts are available for P4::run
. For example:
$p4->run_command( "args" );
is equivalent to:
$p4->run( "command", args );
There are also some shortcuts for common commands such as editing Helix server forms and submitting. For example, this:
<?php
$p4 = new P4();
$p4->connect();
$clientspec = array_pop( $p4->run_client( "-o" ));
$clientspec["Description"] = "Build Client";
$p4->input = $clientspec;
$p4->run_client( "-i" );
$p4->disconnect();
?>
may be shortened to:
<?php
$p4 = new P4();
$p4->connect();
$clientspec = $p4->fetch_spec();
$clientspec["Description"] = "Build client";
$p4->save_client( $clientspec );
$p4->disconnect();
?>
The following are equivalent:
Shortcut | Equivalent to |
---|---|
|
|
|
|
|
|
As the commands associated with
P4::fetch_<spectype>()
typically return only
one item, these methods do not return an array, but instead return the
first result element.
For convenience in submitting changelists, changes returned by
P4::fetch_change()
can be passed to
P4::run_submit()
. For example:
<?php
$p4 = new P4();
$p4->connect();
$spec = $p4->fetch_change();
$spec["Description"] = "Automated change";
$p4->run_submit( $spec );
$p4->disconnect();
?>
Shorthand for:
P4::run( "cmd", arguments... );
Runs a p4 filelog
on the fileSpec provided
and returns an array of P4_DepotFile
results (when
executed in tagged mode), or an array of strings when executed in
nontagged mode. By default, the raw output of p4
filelog
is tagged; this method restructures the output
into a more user-friendly (and object-oriented) form.
For example:
<?php
$p4 = new P4();
try {
$p4->connect();
$filelog = $p4->run_filelog( "index.html" );
foreach ( $filelog->revisions as $revision ) {
// do something
}
} catch ( P4_Exception $e ) {
print $e->getMessage() . "\n";
foreach ( $p4->errors as $error ) {
print "Error: $error\n";
}
}
?>
Runs p4 login
using a password or ticket set by the
user.
A thin wrapper to make it easy to change your password. This method is equivalent to the following:
<?php
$p4->input = array( $oldpass, $newpass, $newpass );
$p4->run( "password" );
?>
For example:
<?php
$p4 = new P4();
$p4->password = "myoldpass";
try {
$p4->connect();
$p4->run_password( "myoldpass", "mynewpass" );
$p4->disconnect();
} catch ( P4_Exception $e ) {
print $e->getMessage() . "\n";
foreach ( $p4->errors as $error ) {
print "Error: $error\n";
}
}
?>
Run a p4 resolve
command. Interactive resolves
require the <resolver> parameter to be an object of a class
derived from P4_Resolver
. In these cases, the
P4::Resolver::resolve()
method is called to handle the
resolve. For example:
<?php
$p4->run_resolve( new MyResolver() );
?>
To perform an automated merge that skips whenever conflicts are detected:
<?php
class MyResolver extends P4_Resolver {
public function resolve( $merge_data ) {
if ( $merge_data->merge_hint != 'e' ) {
return $merge_data->merge_hint;
} else {
return "s"; // skip, there's a conflict
}
}
}
?>
In non-interactive resolves, no P4_Resolver
object
is required. For example:
$p4->run_resolve ( "-at" );
Submit a changelist to the server. To submit a changelist, set the fields of the changelist as required and supply any flags:
$p4->change = $p4->fetch_change();
$change["Description"] = "Some description";
$p4->run_submit( "-r", $change );
You can also submit a changelist by supplying the arguments as you would on the command line:
$p4->run_submit( "-d", "Some description", "somedir/..." );
The save_<spectype>()
methods are shortcut
methods that allow you to quickly update the definitions of clients,
labels, branches, etc. They are equivalent to:
$p4->input = $arrayOrString;
$p4->run( "<spectype> ", "-i" );
For example:
<?php
$p4 = new P4();
try {
$p4->connect();
$client = $p4->fetch_client();
$client["Owner"] = $p4->user;
$p4->save_client( $client );
$p4->disconnect();
} catch ( P4_Exception $e ) {
print $e->getMessage() . "\n";
foreach ( $p4->errors as $error ) {
print "Error: $error\n";
}
}
?>