# Child Workflows - PHP SDK

> Start a Child Workflow Execution within a parent Workflow using Temporal in PHP. Configure ChildWorkflowOptions, handle Parent Close Policy, and implement asynchronous calls with promises.

## How to start a Child Workflow Execution 

A [Child Workflow Execution](/child-workflows) is a Workflow Execution that is scheduled from within another Workflow using a Child Workflow API.

When using a Child Workflow API, Child Workflow related Events ([StartChildWorkflowExecutionInitiated](/references/events#startchildworkflowexecutioninitiated), [ChildWorkflowExecutionStarted](/references/events#childworkflowexecutionstarted), [ChildWorkflowExecutionCompleted](/references/events#childworkflowexecutioncompleted), etc...) are logged in the Workflow Execution Event History.

The [ChildWorkflowExecutionStarted](/references/events#childworkflowexecutionstarted) Event must be logged to the Event History before the Parent Workflow completes to ensure the Child Workflow has started.
In PHP, yielding `$child->start()` or `Workflow::executeChildWorkflow()` internally waits for this Event before returning, so the Child Workflow is guaranteed to have started once the yield resolves.
See the [Parent Close Policy](#parent-close-policy) section below for an example.

Besides Activities, a Workflow can also start other Workflows.

`Workflow::executeChildWorkflow` and `Workflow::newChildWorkflowStub` enables the scheduling of other Workflows from within a Workflow's implementation.
The parent Workflow has the ability to monitor and impact the lifecycle of the Child Workflow, similar to the way it does for an Activity that it invoked.

```php
// Use one stub per child workflow run
$child = Workflow::newChildWorkflowStub(
    ChildWorkflowInterface::class,
    ChildWorkflowOptions::new()
        // Do not specify WorkflowId if you want Temporal to generate a unique Id
        // for the child execution.
        ->withWorkflowId('BID-SIMPLE-CHILD-WORKFLOW')
        ->withExecutionStartToCloseTimeout(DateInterval::createFromDateString('30 minutes'))
);

// This is a non blocking call that returns immediately.
// Use yield $child->workflowMethod(name) to call synchronously.
$promise = $child->workflowMethod('value');

// Do something else here.
try{
    $value = yield $promise;
} catch(TemporalException $e) {
    $logger->error('child workflow failed');
    throw $e;
}
```

Let's take a look at each component of this call.

Before calling `$child->workflowMethod()`, you must configure `ChildWorkflowOptions` for the invocation.
These options customize various execution timeouts, and are passed into the Workflow stub defined by the `Workflow::newChildWorkflowStub`.
Once stub created you can invoke its Workflow method based on attribute `WorkflowMethod`.

The method call returns immediately and returns a `Promise`.
This allows you to execute more code without having to wait for the scheduled Workflow to complete.

When you are ready to process the results of the Workflow, call the `yield $promise` method on the returned promise object.

When a parent Workflow is cancelled by the user, the Child Workflow can be cancelled or abandoned based on a configurable child policy.

You can also skip the stub part of Child Workflow initiation and use `Workflow::executeChildWorkflow` directly:

```php
// Use one stub per child workflow run
$childResult = yield Workflow::executeChildWorkflow(
    'ChildWorkflowName',
    ['args'],
    ChildWorkflowOptions::new()->withWorkflowId('BID-SIMPLE-CHILD-WORKFLOW'),
    Type::TYPE_STRING // optional: defines the return type
);
```

#### How to set a Parent Close Policy 

A [Parent Close Policy](/parent-close-policy) determines what happens to a Child Workflow Execution if its Parent changes to a Closed status (Completed, Failed, or Timed Out).

The default Parent Close Policy option is set to terminate the Child Workflow Execution.

In PHP, a [Parent Close Policy](/parent-close-policy) is set via the `ChildWorkflowOptions` object and `withParentClosePolicy()` method.
The possible values can be obtained from the [`ParentClosePolicy`](https://github.com/temporalio/sdk-php/blob/master/src/Workflow/ParentClosePolicy.php) class.

- `POLICY_TERMINATE`
- `POLICY_ABANDON`
- `POLICY_REQUEST_CANCEL`

Then `ChildWorkflowOptions` object is used to create a new Child Workflow object:

```php
$child = Workflow::newUntypedChildWorkflowStub(
    'child-workflow',
    ChildWorkflowOptions::new()
        ->withParentClosePolicy(ParentClosePolicy::POLICY_ABANDON)
);

yield $child->start();
```

In the snippet above we:

1. Create a new untyped Child Workflow stub with `Workflow::newUntypedChildWorkflowStub`.
2. Provide `ChildWorkflowOptions` object with Parent Close Policy set to `ParentClosePolicy::POLICY_ABANDON`.
3. Start Child Workflow Execution asynchronously using `yield` and method `start()`.

We need `yield` here to ensure that a Child Workflow Execution starts before the parent closes.
