Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8437259
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T07:22:57+00:00 2026-06-10T07:22:57+00:00

I am creating a PHP extension in C to access the SPI interface. So

  • 0

I am creating a PHP extension in C to access the SPI interface. So far I have gotten pretty much everything working: php_spi on Github

However, I cannot seem to make the $options parameter in the constructor optional. My working code is like this:

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lla", &bus, &chipselect, &options) == FAILURE) {
    return;
}

_this_zval = getThis();
_this_ce = Z_OBJCE_P(_this_zval);

options_hash = HASH_OF(options);

char device[32];
sprintf(device, "/dev/spidev%d.%d", bus, chipselect);

// If the device doesn't exists, error!
if(access(device, F_OK) == -1) {
    char error[128];
    sprintf(error, "The device %s does not exist", device);
    php_error(E_ERROR, error);
}

// If we can't open it, error!
long fd = open(device, O_RDWR);
if (fd < 0) {
    char error[128];
    sprintf(error, "Could not open %s for read/write operations, are you running as root?", device);
    php_error(E_ERROR, error);
}

// Set the file descriptor as a class property
zend_update_property_long(_this_ce, _this_zval, "device", 6, fd TSRMLS_DC);

// Default property values
uint8_t mode = SPI_MODE_0;
uint8_t bits = 8;
uint32_t speed = 500000;
uint16_t delay = 0;

// Loop through the options array
zval **data;
for(zend_hash_internal_pointer_reset(options_hash);
    zend_hash_get_current_data(options_hash, (void **)&data) == SUCCESS;
    zend_hash_move_forward(options_hash)) {

    char *key;
    int len;
    long index;
    long value = Z_LVAL_PP(data);

    if(zend_hash_get_current_key_ex(options_hash, &key, &len, &index, 1, NULL) == HASH_KEY_IS_STRING) {
        // Assign the value accordingly
        if(strncmp("mode", key, len) == 0) {
            switch(value) {
                case SPI_MODE_1:
                    mode = SPI_MODE_1;
                    break;
                case SPI_MODE_2:
                    mode = SPI_MODE_2;
                    break;
                case SPI_MODE_3:
                    mode = SPI_MODE_3;
                    break;
                default:
                    mode = SPI_MODE_0;
                    break;
            }
        }
        else if(strncmp("bits", key, len) == 0) {
            bits = value;
        }
        else if(strncmp("speed", key, len) == 0) {
            speed = value;
        }
        else if(strncmp("delay", key, len) == 0) {
            delay = value;
        }
    }
}

However, if I follow the suggestions of all the documentation I can find and add a pipe between the l and the a, like so:

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll|a", &bus, &chipselect, &options) == FAILURE) {

Then my extension silently fails – can anyone offer me any advice?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T07:22:58+00:00Added an answer on June 10, 2026 at 7:22 am

    Assuming options is a zval*, if you do this:

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll|a", &bus, &chipselect, &options) == FAILURE) {
        return;
    }
    

    …if options is not passed (that is, you omit the third optional argument), options will not be initialized or modified. Later, you do this:

    options_hash = HASH_OF(options);
    

    Therefore, you’re using either an uninitialized pointer, or a NULL pointer, which is undefined behavior. This is most likely causing a segmentation fault, causing your PHP script to fail.

    What you should do is something like:

    zval* options = NULL;
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll|a", &bus, &chipselect, &options) == FAILURE) {
        return;
    }
    
    // ...
    
    if (options != NULL) {
        options_hash = HASH_OF(options);
    }
    

    …and handle every instance of options (and options_hash) with a condition that checks if it’s NULL or not.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm dabbling with creating a PHP extension for a personal project. Beyond what's linked
What are first steps creating a loadable DLL module extension for PHP to create
I am creating a php backup script that will dump everything from a database
I have written some C/C++ extension modules for PHP, using the 'old fashioned way'
I have been working on creating an application that sends a string from an
Can I use a PHP function such as explode() when creating an extension in
what i want to do is that i am creating php array dynamic .i
I am creating a PHP application for my company and I am using about
hi friends i'm creating a php page to import the data from a csv
I'm new to PHP and I am currently creating a PHP web application for

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.