2

I am working in c++ under ubuntu. I have the following example: [car.h]

#ifndef VEHICLES_CAR_H
#define VEHICLES_CAR_H

// A very simple car class
class Car {
public:
    Car();
    void shift(int gear);
    bool accelerate();
    void brake();
    int getCurrentSpeed();
    int getCurrentGear();
public:
    int maxGear;
    int currentGear;
    int speed;
};

#endif /* VEHICLES_CAR_H *

/ [car.cc]

#include "car.hpp"
#include "car2.hpp"
#include "car2.cc"
#include "car3.h"
#include "car3.cc"
#include <stdio.h>
#include <iostream>
using namespace std;

Car::Car() {

}

void Car::shift(int gear) {
    if (gear < 1 || gear > maxGear) {
        return;
    }
    currentGear = gear;
}
bool Car::accelerate() {
    speed = 10;
    if (speed == 10) return true;
    else return false;
}

void Car::brake() {
    speed -= (5 *5);
}

int Car::getCurrentSpeed() {
    Hello h; //this is in another class...it's working ok
    h.say_hello();
    speed=5;
    return speed;
}

int Car::getCurrentGear() {
    return currentGear;
}

[vehicles.cc]

#include "php_vehicles.h"
#include "car.hpp"

zend_object_handlers car_object_handlers;

struct car_object {
    zend_object std;
    Car *car;
};

zend_class_entry *car_ce;

void car_free_storage(void *object TSRMLS_DC)
{
    car_object *obj = (car_object *)object;
    delete obj->car; 

    zend_hash_destroy(obj->std.properties);
    FREE_HASHTABLE(obj->std.properties);

    efree(obj);
}

zend_object_value car_create_handler(zend_class_entry *type TSRMLS_DC)
{
    zval *tmp;
    zend_object_value retval;

    car_object *obj = (car_object *)emalloc(sizeof(car_object));
    memset(obj, 0, sizeof(car_object));
    obj->std.ce = type;

    ALLOC_HASHTABLE(obj->std.properties);
    zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
    zend_hash_copy(obj->std.properties, &type->default_properties,
        (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));

    retval.handle = zend_objects_store_put(obj, NULL,
        car_free_storage, NULL TSRMLS_CC);
    retval.handlers = &car_object_handlers;

    return retval;
}


PHP_METHOD(Car, __construct)
{
    long maxGear;
    Car *car = NULL;
    zval *object = getThis();

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "", NULL) == FAILURE) {
        RETURN_NULL();
    }

    car = new Car();
    car_object *obj = (car_object *)zend_object_store_get_object(object TSRMLS_CC);
    obj->car = car;

}
PHP_METHOD(Car, shift)
{
}
PHP_METHOD(Car, accelerate)
{
    Car *car;
    car_object *obj = (car_object *)zend_object_store_get_object(
        getThis() TSRMLS_CC);
    car = obj->car;
    if (car != NULL) {
       RETURN_BOOL( car->accelerate());
       RETURN_LONG(car->speed);
    }

}
PHP_METHOD(Car, brake)
{
}
PHP_METHOD(Car, getCurrentSpeed)
{
    Car *car;
    car_object *obj = (car_object *)zend_object_store_get_object(
        getThis() TSRMLS_CC);
    car = obj->car;
    if (car != NULL) {
        RETURN_LONG(car->getCurrentSpeed());
    }
    RETURN_NULL();

}
PHP_METHOD(Car, getCurrentGear)
{
}

function_entry car_methods[] = {
    PHP_ME(Car,  __construct,     NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
    PHP_ME(Car,  shift,           NULL, ZEND_ACC_PUBLIC)
    PHP_ME(Car,  accelerate,      NULL, ZEND_ACC_PUBLIC)
    PHP_ME(Car,  brake,           NULL, ZEND_ACC_PUBLIC)
    PHP_ME(Car,  getCurrentSpeed, NULL, ZEND_ACC_PUBLIC)
    PHP_ME(Car,  getCurrentGear,  NULL, ZEND_ACC_PUBLIC)
    {NULL, NULL, NULL}
};

PHP_MINIT_FUNCTION(vehicles)
{
   zend_class_entry ce;
    INIT_CLASS_ENTRY(ce, "Car", car_methods);
    car_ce = zend_register_internal_class(&ce TSRMLS_CC);
    car_ce->create_object = car_create_handler;
    memcpy(&car_object_handlers,
        zend_get_std_object_handlers(), sizeof(zend_object_handlers));
    car_object_handlers.clone_obj = NULL;
    return SUCCESS;

}

zend_module_entry vehicles_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
    STANDARD_MODULE_HEADER,
#endif
    PHP_VEHICLES_EXTNAME,
    NULL,        /* Functions */
    PHP_MINIT(vehicles),        /* MINIT */
    NULL,        /* MSHUTDOWN */
    NULL,        /* RINIT */
    NULL,        /* RSHUTDOWN */
    NULL,        /* MINFO */
#if ZEND_MODULE_API_NO >= 20010901
    PHP_VEHICLES_EXTVER,
#endif
    STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_VEHICLES
extern "C" {
ZEND_GET_MODULE(vehicles)
}
#endif

[php_vehicles.h]

  #ifndef PHP_VEHICLES_H
#define PHP_VEHICLES_H

#define PHP_VEHICLES_EXTNAME  "vehicles"
#define PHP_VEHICLES_EXTVER   "0.1"

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif 

#ifdef __cplusplus
extern "C" {
    #endif
#ifdef ZTS
#include "TSRM.h"
#endif
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
    #endif
#include "php.h"

#ifdef __cplusplus
}
#endif


extern zend_module_entry vehicles_module_entry;
#define phpext_vehicles_ptr &vehicles_module_entry;

#endif /* PHP_VEHICLES_H */

[config.m4]

    PHP_ARG_ENABLE(vehicles,
    [Whether to enable the "vehicles" extension],
    [  --enable-vehicles      Enable "vehicles" extension support])

if test $PHP_VEHICLES != "no"; then
    PHP_REQUIRE_CXX()
    PHP_SUBST(VEHICLES_SHARED_LIBADD)
    PHP_ADD_LIBRARY(stdc++, 1, VEHICLES_SHARED_LIBADD)
    PHP_NEW_EXTENSION(vehicles, vehicles.cc car.cc, $ext_shared)
fi

[test.php]

<html>
    <head>
        <title>MY FIRST PHP EXTENSION</title>
    </head>
    <body>
<?php


$car = new Car();
echo "FIRST RESULT: ".$car->getCurrentSpeed()." ";  // prints '0'
//echo "CAR IS: ".$car->accelerate();
if ($car->accelerate() == True) { echo "IT IS TRUE AND SPEED IS: ". $car->$speed;}

//echo "SECOND RESULT: ". $car->getCurrentSpeed()." "; // prints '5'
?>

    </body>
</html>

I have the following error at line $car->$speed:  Undefined variable: speed in /home/test.php on line 13
PHP Fatal error:  Cannot access empty property 

WHY? How to solve this? thx ! appreciate

2 Answers 2

1

Change $car->$speed to $car->getCurrentSpeed():

if ($car->accelerate() == True) { echo "IT IS TRUE AND SPEED IS: ". $car->getCurrentSpeed();}
Sign up to request clarification or add additional context in comments.

5 Comments

what if i would like to print the speed - the variable and not the function. How to solve this? THX!
The method gets the current value of speed (from the C++ class). I don't believe it is possible to access the c++ variable directly from PHP. You need to have getter and setter methods in your c++ class to allow access to variables from PHP. Your getCurrentSpeed method should just contain return speed;.
i see. So if I want to print all the variables from the Car class is there a possible way to print them all in one function?(what to do to print speed, currentGear and maxGear in a single method)?
Call all the getter methods from PHP and echo the values returned. Alternatively add a new c++ method that returns a string to PHP containing everything to be echoed.
qbert i would like to ask you: if the class Car was inside a class Machines like: class Machines {class Car.....}; what should i change in my vehicles.cc code? please help
0

Calling $car->$speed property you should firs define $speed variable.

$speed = 'speed'; // You should define this in PHP code before calling $car->$speed

Calling $car->$speed assumes that you call $car->speed because $speed defined as 'speed'.

It's PHP part of the code.

Or you can simply call $car->speed if you need to access the 'speed' property of $car object

5 Comments

how to define speed variable? Please give me an example based on what i wrote
where to add this?in vehicles.cc? can you please be more specific? i am new to php
i did use $car->speed but it's not working. i have the error: Undefined property: Car::$speed
I think you should define public 'speed' property in your C++ class. And then access it by $car->speed
int speed is public. or what do you mean?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.