You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iggy.apache.org by "countradooku (via GitHub)" <gi...@apache.org> on 2026/05/29 07:57:28 UTC
[PR] Add PHP SDK examples component [iggy]
countradooku opened a new pull request, #3368:
URL: https://github.com/apache/iggy/pull/3368
## Summary
- add PHP SDK examples under `examples/php` for getting-started and basic producer/consumer flows
- add an `examples-php` component entry with PHP SDK, Rust SDK, Rust server, and CI infrastructure dependencies
- wire PHP examples into `_test_examples.yml` and `scripts/run-examples-from-readme.sh`
Closes #3311.
## Validation
- `php -l` for all PHP example files
- `bash -n scripts/run-examples-from-readme.sh`
- `git diff --check`
- `./scripts/ci/markdownlint.sh examples/php/README.md`
- `./scripts/ci/license-headers.sh --check`
- `cargo build --locked --bin iggy-server`
- `cargo build` in `foreign/php`
- pre-push hook: cargo clippy passed; Go lint suites passed; Java/C# skipped as no relevant files changed
## Local caveats
- normal commit hook was blocked locally by missing `shellcheck` and macOS Bash lacking `mapfile` for `scripts/ci/sync-python-version.sh`; commit used `--no-verify` after running the targeted checks above
- `prek run --all-files` also needs local tools that are not installed here (`yq`, `taplo`, `cargo-sort`, Node `eslint`)
- full PHP example runner was not completed on macOS because the local `iggy-server` process did not emit the readiness marker and logged memory binding failures
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@iggy.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] feat(php): add SDK examples component [iggy]
Posted by "hubcio (via GitHub)" <gi...@apache.org>.
hubcio commented on code in PR #3368:
URL: https://github.com/apache/iggy/pull/3368#discussion_r3323385003
##########
scripts/run-examples-from-readme.sh:
##########
@@ -284,6 +284,49 @@ run_python_examples() {
return "${EXAMPLES_EXIT_CODE}"
}
+# shellcheck disable=SC2329
+run_php_examples() {
+ resolve_server_binary "${TARGET}"
+
+ local php_bin="${PHP:-php}"
+ if [ -z "${PHP_IGGY_EXTENSION:-}" ]; then
+ local extension_candidate
+ for extension_candidate in \
+ target/debug/libiggy_php.so \
+ target/debug/libiggy_php.dylib \
+ target/debug/iggy_php.dll \
+ foreign/php/target/debug/libiggy_php.so \
+ foreign/php/target/debug/libiggy_php.dylib \
+ foreign/php/target/debug/iggy_php.dll; do
+ if [ -f "${extension_candidate}" ]; then
+ PHP_IGGY_EXTENSION="${extension_candidate}"
Review Comment:
this sets `PHP_IGGY_EXTENSION` to a repo-root-relative path, but `run_language_examples` cds into `examples/php` before the readme command evals `php -d extension="${PHP_IGGY_EXTENSION:-...}"`. the var is now set so the `:-` fallback is skipped, and the relative path resolves against `examples/php/` -> file missing -> extension fails to load -> `Iggy\Client` undefined -> fatal. the `[ ! -f ]` check above runs while still at repo root so it passes and masks it. CI is fine since the workflow exports an absolute `realpath`, but `./scripts/run-examples-from-readme.sh --language php` run locally hits it. fix: `PHP_IGGY_EXTENSION="$(pwd)/${extension_candidate}"`. also the `iggy_php.dll` candidates are dead here (no windows runner) and can be dropped.
##########
examples/php/src/common.php:
##########
@@ -0,0 +1,96 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+declare(strict_types=1);
+
+use Iggy\Client;
+use Iggy\PollingStrategy;
+use Iggy\ReceiveMessage;
+use Iggy\SendMessage;
+
+function iggy_connection_string(): string
+{
+ $configured = getenv('IGGY_CONNECTION_STRING');
+ if ($configured !== false && $configured !== '') {
+ return $configured;
+ }
+
+ $host = getenv('IGGY_HOST') ?: '127.0.0.1';
+ $port = getenv('IGGY_PORT') ?: '8090';
+ $username = rawurlencode(getenv('IGGY_USERNAME') ?: 'iggy');
+ $password = rawurlencode(getenv('IGGY_PASSWORD') ?: 'iggy');
+
+ return "iggy+tcp://{$username}:{$password}@{$host}:{$port}";
+}
+
+function iggy_client(): Client
+{
+ $client = Client::fromConnectionString(iggy_connection_string());
+ $client->connect();
+
+ return $client;
+}
+
+function ensure_stream_and_topic(Client $client, string $stream, string $topic): void
+{
+ if ($client->getStream($stream) === null) {
+ $client->createStream($stream);
+ }
+
+ if ($client->getTopic($stream, $topic) === null) {
+ $client->createTopic($stream, $topic, 1, null, null, null, null);
+ }
+}
+
+function send_payloads(Client $client, string $stream, string $topic, array $payloads): void
+{
+ $messages = array_map(
+ static fn (string $payload): SendMessage => new SendMessage($payload),
+ $payloads,
+ );
+
+ $client->sendMessages($stream, $topic, 0, $messages);
+}
+
+function print_polled_messages(Client $client, string $stream, string $topic, int $count): void
+{
+ $messages = $client->pollMessages($stream, $topic, 0, PollingStrategy::first(), $count, true);
+
+ if (count($messages) < $count) {
+ throw new RuntimeException("Expected {$count} messages, received " . count($messages));
+ }
+
+ foreach ($messages as $message) {
+ if (!$message instanceof ReceiveMessage) {
Review Comment:
`pollMessages()` always returns an array of `ReceiveMessage`, so this guard can never be false and the `continue` is unreachable. drop it and iterate directly.
##########
examples/php/src/common.php:
##########
@@ -0,0 +1,96 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+declare(strict_types=1);
+
+use Iggy\Client;
+use Iggy\PollingStrategy;
+use Iggy\ReceiveMessage;
+use Iggy\SendMessage;
+
+function iggy_connection_string(): string
+{
+ $configured = getenv('IGGY_CONNECTION_STRING');
+ if ($configured !== false && $configured !== '') {
+ return $configured;
+ }
+
+ $host = getenv('IGGY_HOST') ?: '127.0.0.1';
+ $port = getenv('IGGY_PORT') ?: '8090';
+ $username = rawurlencode(getenv('IGGY_USERNAME') ?: 'iggy');
+ $password = rawurlencode(getenv('IGGY_PASSWORD') ?: 'iggy');
+
+ return "iggy+tcp://{$username}:{$password}@{$host}:{$port}";
+}
+
+function iggy_client(): Client
+{
+ $client = Client::fromConnectionString(iggy_connection_string());
+ $client->connect();
+
+ return $client;
+}
+
+function ensure_stream_and_topic(Client $client, string $stream, string $topic): void
+{
+ if ($client->getStream($stream) === null) {
+ $client->createStream($stream);
+ }
+
+ if ($client->getTopic($stream, $topic) === null) {
+ $client->createTopic($stream, $topic, 1, null, null, null, null);
Review Comment:
the 4 trailing `null`s match the stub defaults, so `createTopic($stream, $topic, 1)` is equivalent and cleaner. the python example skips them too.
##########
examples/php/README.md:
##########
@@ -0,0 +1,38 @@
+# Iggy PHP Examples
+
+This directory contains sample applications that show how to use the Apache
+Iggy PHP SDK extension.
+
+## Running Examples
+
+Start the server from the repository root:
+
+```bash
+cargo run --bin iggy-server -- --fresh --with-default-root-credentials
+```
+
+From `examples/php`, build the PHP extension and point PHP at it:
+
+```bash
+(cd ../../foreign/php && cargo build)
+export PHP_IGGY_EXTENSION="$(pwd)/../../foreign/php/target/debug/libiggy_php.so"
+```
+
+On macOS, use `../../foreign/php/target/debug/libiggy_php.dylib` instead.
+
+### Getting Started
+
+```bash
+php -d extension="${PHP_IGGY_EXTENSION:-../../foreign/php/target/debug/libiggy_php.so}" getting-started/producer.php
+php -d extension="${PHP_IGGY_EXTENSION:-../../foreign/php/target/debug/libiggy_php.so}" getting-started/consumer.php
+```
+
+### Basic Usage
+
+```bash
+php -d extension="${PHP_IGGY_EXTENSION:-../../foreign/php/target/debug/libiggy_php.so}" basic/producer.php
+php -d extension="${PHP_IGGY_EXTENSION:-../../foreign/php/target/debug/libiggy_php.so}" basic/consumer.php
+```
+
+The examples use `IGGY_CONNECTION_STRING` when it is set. Otherwise they connect
Review Comment:
the examples also fall back to `IGGY_HOST`, `IGGY_PORT`, `IGGY_USERNAME` and `IGGY_PASSWORD` when `IGGY_CONNECTION_STRING` is unset, but only the connection string is documented here. worth a line so people know the individual vars work too.
##########
scripts/run-examples-from-readme.sh:
##########
@@ -284,6 +284,49 @@ run_python_examples() {
return "${EXAMPLES_EXIT_CODE}"
}
+# shellcheck disable=SC2329
+run_php_examples() {
+ resolve_server_binary "${TARGET}"
+
+ local php_bin="${PHP:-php}"
+ if [ -z "${PHP_IGGY_EXTENSION:-}" ]; then
+ local extension_candidate
+ for extension_candidate in \
+ target/debug/libiggy_php.so \
+ target/debug/libiggy_php.dylib \
+ target/debug/iggy_php.dll \
+ foreign/php/target/debug/libiggy_php.so \
+ foreign/php/target/debug/libiggy_php.dylib \
+ foreign/php/target/debug/iggy_php.dll; do
+ if [ -f "${extension_candidate}" ]; then
+ PHP_IGGY_EXTENSION="${extension_candidate}"
+ break
+ fi
+ done
+ export PHP_IGGY_EXTENSION
+ fi
+
+ if [ -z "${PHP_IGGY_EXTENSION:-}" ] || [ ! -f "${PHP_IGGY_EXTENSION}" ]; then
+ echo "Error: PHP extension not found. Build foreign/php first or set PHP_IGGY_EXTENSION."
+ exit 1
+ fi
+
+ TRANSFORM_COMMAND() {
+ local command="$1"
+ printf '%s\n' "${command/#php /\"${php_bin}\" }"
+ }
+
+ run_language_examples \
+ "PHP" \
+ "examples/php" \
+ "README.md" \
+ "^php " \
+ "" \
+ "" \
+ 0 \
Review Comment:
non-blocking and the other runners pass `0` too, so fine to leave - but `0` means no per-command timeout, and `connect()` retries unbounded by default. if the server dies after startup a stalled connect rides all the way to the 60-min job timeout instead of failing fast. python passes `10`. could be a small repo-wide follow-up.
##########
examples/php/basic/producer.php:
##########
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+declare(strict_types=1);
+
+require_once __DIR__ . '/../src/common.php';
+
+$stream = 'php-basic-stream';
+$topic = 'php-basic-topic';
+$client = iggy_client();
+
+ensure_stream_and_topic($client, $stream, $topic);
+send_payloads($client, $stream, $topic, [
Review Comment:
small consistency thing - the getting-started producer builds payloads via `example_payloads()` while this one uses an inline array. could call `example_payloads('basic', 3)` here so both follow one style.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@iggy.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] feat(php): add SDK examples component [iggy]
Posted by "countradooku (via GitHub)" <gi...@apache.org>.
countradooku commented on PR #3368:
URL: https://github.com/apache/iggy/pull/3368#issuecomment-4574617719
/ready
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@iggy.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] feat(php): add SDK examples component [iggy]
Posted by "hubcio (via GitHub)" <gi...@apache.org>.
hubcio merged PR #3368:
URL: https://github.com/apache/iggy/pull/3368
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@iggy.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] feat(php): add SDK examples component [iggy]
Posted by "codecov[bot] (via GitHub)" <gi...@apache.org>.
codecov[bot] commented on PR #3368:
URL: https://github.com/apache/iggy/pull/3368#issuecomment-4572385853
## [Codecov](https://app.codecov.io/gh/apache/iggy/pull/3368?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
:white_check_mark: All modified and coverable lines are covered by tests.
:white_check_mark: Project coverage is 72.77%. Comparing base ([`397533f`](https://app.codecov.io/gh/apache/iggy/commit/397533f4bdf2c5eb74bed70c0276d601b1fd2bc9?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)) to head ([`56bef25`](https://app.codecov.io/gh/apache/iggy/commit/56bef25624e05a44bee07a9497be5af00ff38cbc?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)).
<details><summary>Additional details and impacted files</summary>
```diff
@@ Coverage Diff @@
## master #3368 +/- ##
============================================
- Coverage 73.69% 72.77% -0.92%
Complexity 943 943
============================================
Files 1223 1160 -63
Lines 115710 110903 -4807
Branches 92447 92358 -89
============================================
- Hits 85270 80712 -4558
+ Misses 27577 27325 -252
- Partials 2863 2866 +3
```
| [Components](https://app.codecov.io/gh/apache/iggy/pull/3368/components?src=pr&el=components&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | |
|---|---|---|
| [Rust Core](https://app.codecov.io/gh/apache/iggy/pull/3368/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `74.69% <ø> (ø)` | |
| [Java SDK](https://app.codecov.io/gh/apache/iggy/pull/3368/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `58.44% <ø> (ø)` | |
| [C# SDK](https://app.codecov.io/gh/apache/iggy/pull/3368/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `69.96% <ø> (ø)` | |
| [Python SDK](https://app.codecov.io/gh/apache/iggy/pull/3368/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `81.06% <ø> (ø)` | |
| [Node SDK](https://app.codecov.io/gh/apache/iggy/pull/3368/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `87.48% <ø> (-4.06%)` | :arrow_down: |
| [Go SDK](https://app.codecov.io/gh/apache/iggy/pull/3368/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `40.20% <ø> (ø)` | |
[see 81 files with indirect coverage changes](https://app.codecov.io/gh/apache/iggy/pull/3368/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
</details>
<details><summary> :rocket: New features to boost your workflow: </summary>
- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@iggy.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org