Page 1 of 1

Can PHP realize something like structure in C

Posted: Mon Jul 29, 2002 2:00 am
by lixmde
:?: In C, it is very easy to realize this:

typedef struct user {
int ID;
char name[50]; //fixed length
}

fwrite(fp, lpbuffer, sizeof(struct user);

can PHP provide the similar function? Any sugguestion will be appreciated

Posted: Mon Jul 29, 2002 7:41 am
by volka
you may use classes and serialize them

Posted: Mon Jul 29, 2002 8:40 am
by BDKR
I've thought about this too. The only thing I could think of that would come close would be a class that ecapsulates the data you wish to store/work with in addition to having a way to get and set that data. Hopefully with that, you could mimic (somewhat) the use and advantages of a structure.

Just an idea..... :?

Later on,
BDKR

Posted: Mon Jul 29, 2002 8:42 am
by llimllib
Since all variables in PHP are public, a class with no methods should be exactly the same as a strct in C, I believe.

Posted: Mon Jul 29, 2002 10:31 am
by BDKR
You know, I didn't think you could create a class in PHP without methods, but I just got away with it. However, if there is a need to iterate over those vars, ?

Code: Select all

<?php
# Test a class with no methods

class Struct
  &#123;
  var $count = 0;
  var $initial = B;
  &#125;

# Instantiate object
$my_struct = new Struct;

# Echo a value
echo $my_struct->initial;

# Change a value
$my_struct->count = 1;

# Echo the value that was just changed
echo $my_struct->count; echo "\n";
?>
Now this all works, but I still can't think of how one would iterate over the vars in the struct object........ wait a sec ..........

OK, you could use something like this to iterate over the values if need be.

Code: Select all

# Remember, $my_struct is the object. Also, I am just echoing the information 
# back for the example. One can do whatever they wish between the "&#123; &#125;"'s. 
while(list($key, $data)=each($my_struct))
    &#123; echo "$key = $data"; &#125;
When you get right down to it, there is a ton of things that can be done. And this is no doubt a way of creating structures. However, I can't help but wonder how slow it is comparitively speaking as we are using objects. I am willing to bet that something like

Code: Select all

$struct array(
    $count => "0",
    $initial => "B"
    );
would be faster. But of course, the advantage of objects is that they can act as templates that are easily recreated.

Blah blah blah..... I'll shut up now..... :?
Later on,
BDKR

Posted: Mon Jul 29, 2002 11:10 am
by llimllib
I agree entirely, the speed is probably going to be very poor compared to either an array or a C struct.

Posted: Mon Jul 29, 2002 12:36 pm
by Matt Wade
Using a class rather than array seems to run about 10-12% slower in my tests. Here is a simple test script I used:

Code: Select all

<?
function getmicrotime()&#123; 
	list($usec, $sec) = explode(" ",microtime()); 
	return ((float)$usec + (float)$sec); 
&#125; 

class Struct &#123;
	var $count = 0;
&#125;

$time_start = getmicrotime();
$struct = new Struct;

for($i = 0;$i < 100000; $i++) &#123;
	$struct->count = $i;
&#125;
$time_end = getmicrotime();
echo "Using a class took: " . ($time_end - $time_start) . "seconds.<BR>\n";

$time_start = getmicrotime();
$array = array(1 => 0);

for($i = 0;$i < 100000; $i++) &#123;
	$array&#1111;1] = $i;
&#125;
$time_end = getmicrotime();
echo "Using an array took: " . ($time_end - $time_start) . "seconds.<BR>\n";
?>

Posted: Mon Jul 29, 2002 1:22 pm
by BDKR
Yeah I figured as much. Heres something you might want to take a look at along those lines.

http://php.weblogs.com/discuss/msgReader$537?mode=day

Later on,
BDKR

Posted: Fri Sep 26, 2003 9:54 pm
by McGruff
Recently hit upon this same idea with the aim of clarifying some class scripts.

Suppose you have a relatively busy class: there's all kinds of "intermediate" vars in there which you use to build maybe half a dozen or so output vars. Creating a method-less object to encapsulate just the output vars helped focus what is actually printing out from the morass of code.

Although there's no real need for any kind of interface, adding a single setter and getter lets you attach behaviours to these actions (why I didn't just use an array):

Code: Select all

<?php

class PostPageVars
{

    var $var1 = null;
    var $var2 = null;
    // ..etc..

    function setVar($name, $value) 
    {
        $this->$name = $value;
        echo 'PostPageVars ' . $name . ' is ' . $this->$name . '<br />'; 
    }

    function getVar($name) 
    {
        #/*
        if(is_null($this->$name)) 
        {
            echo $name . ' is null.<br />';
        
        } else {
        
            echo $name . ' is ' . $this->$name . '.<br />';
        }
        #*/
        return $this->$name;                
    }

}
?>
That helped enormously when I began testing a redesigned forum posts list script which has about 8 or 9 interacting objects (echo's are commented on and off as needed).

Methods getVar & setVar could equally provide some handy "sockets" to attach other kinds of behaviour to get and set actions, in other uses.

Posted: Mon Sep 29, 2003 5:54 pm
by BDKR
Matt Wade wrote:Using a class rather than array seems to run about 10-12% slower in my tests. Here is a simple test script I used:

Code: Select all

<?
function getmicrotime(){ 
	list($usec, $sec) = explode(" ",microtime()); 
	return ((float)$usec + (float)$sec); 
} 

class Struct {
	var $count = 0;
}

$time_start = getmicrotime();
$struct = new Struct;

for($i = 0;$i < 100000; $i++) {
	$struct->count = $i;
}
$time_end = getmicrotime();
echo "Using a class took: " . ($time_end - $time_start) . "seconds.<BR>\n";

$time_start = getmicrotime();
$array = array(1 => 0);

for($i = 0;$i < 100000; $i++) {
	$array[1] = $i;
}
$time_end = getmicrotime();
echo "Using an array took: " . ($time_end - $time_start) . "seconds.<BR>\n";
?>
I wonder if these little changes help a little.

Code: Select all

<?
function getmicrotime(){ 
	list($usec, $sec) = explode(" ",microtime()); 
	return ((float)$usec + (float)$sec); 
} 

class Struct {
	var $count = 0;
}

$time_start = getmicrotime();
$struct = new Struct;

for($i = 0;$i < 100000; ++$i) {
	$struct->count = $i;
}
$time_end = getmicrotime();
echo "Using a class took: " . ($time_end - $time_start) . "seconds.<BR>\n";

$time_start = getmicrotime();
$array = array(1 => 0);

for($i = 0;$i < 100000; ++$i) {
	$array['1'] = $i;
}
$time_end = getmicrotime();
echo "Using an array took: " . ($time_end - $time_start) . "seconds.<BR>\n";
?>
I equalized this a bit by making the array element that we are incrementing associative as opposed to indexed. That's more fair. I also pre-incremented as it's faster to do so. Unless there's a specific need to post increment, I feel it's better to pre.

Anyways, I came up with...

Using a class took: 0.255446076393seconds.
Using an array took: 0.288635015488seconds

Curious eh?

Cheers,
BDKR

Posted: Mon Sep 29, 2003 6:08 pm
by BDKR
Sorry that I just can't shut up here. Here's something else that I found. By changing

Code: Select all

$array = array('1' => 0);

for($i = 0;$i < 100000; ++$i) {
	$array['1'] = $i;


to

Code: Select all

$array = array('one' => 0);

for($i = 0;$i < 100000; ++$i) {
	$array['one'] = $i;
Increased the performance of the array to where it's a smidgen faster than using the struct. This is strange to me as '1' and 'one' are both strings and would both be associative elements in the $array array. Is there something I don't know about here?

Cheers,
BDKR

Posted: Mon Sep 29, 2003 6:11 pm
by BDKR
McGruff wrote: Methods getVar & setVar could equally provide some handy "sockets" to attach other kinds of behaviour to get and set actions, in other uses.
This idea of 'sockets' you have sounds interesting. Do you think you could elaborate?

Cheers,
BDKR

Posted: Mon Sep 29, 2003 7:14 pm
by McGruff
A "socket" would be a wrapper of some kind. Suppose you defined a dbQuery() fn:

Code: Select all

<?php
function dbQuery($mysql) 
{
    $query = mysql_query($mysql) OR die('Error: ' . mysql_errno() . ' - ' . mysql_error() . '<br />');
    return $query;
}
?>
dbQuery would be a socket in as much as you can, with a quick edit of the fn def, make an edit across the whole program - maybe to change the error reporting level for live/local or to switch to a db other than mysql.

The getVar & setVar methods in above post would similarly let you attach a behaviour to get/set actions with a quick edit - I used this to help debug a tricky script with lots of interacting objects. Once it was working, I could just discard the echo lines.

The idea is that something is wrapped in something else - a fn in a fn or maybe an object in another, handler object. Throughout a program, the script is calling the wrapper: editing the wrapper def lets you "plug in" a different fn/object/behaviour across the whole program with one quick edit.

Maybe this is one way where a structure might win out over an array. With getVar and setVar you can trigger an action each time you get or set. It's not quite methodless any more but it's still being treated as a container, now with a simple interface.

Must admit I haven't a clue what a structure in C is or is used for so maybe I'm going a bit OT here.