I have two functions which appear to be slowing down PHP, and I believe its to do with the use of array_merge in the loops, only I am struggling to figure out how I can get around not doing so.
function fuseOzone($field) {
global $ozone;
if(isset($ozone['all'])) {
foreach($ozone['all'] as $priority => $functions) {
if(isset($ozone[$field][$priority])) {
$ozone[$field][$priority] = array_merge($ozone['all'][$priority], $ozone[$field][$priority]);
} else {
$ozone[$field][$priority] = array_merge($ozone['all'][$priority], array());
$ozone[$field][$priority] = array_unique($ozone[$field][$priority]);
}
}
}
if(isset($ozone[$field])) {
ksort($ozone[$field]);
}
}
function applyOzone($field, $content) {
global $ozone;
fuseOzone($field);
$args = array_slice(func_get_args(), 2);
if(isset($ozone[$field])) {
foreach($ozone[$field] as $priority => $functions) {
if(!is_null($functions)) {
foreach($functions as $function) {
if(!function_exists($function['function'])) {
continue;
}
$all_args = array_merge(array($content), $args);
$function_name = $function['function'];
$accepted_args = $function['accepted_args'];
if($accepted_args === 1) {
$the_args = array($content);
} elseif($accepted_args > 1) {
$the_args = array_slice($all_args, 0, $accepted_args);
} elseif($accepted_args === 0) {
$the_args = null;
} else {
$the_args = $all_args;
}
$content = call_user_func_array($function_name, $the_args);
}
}
}
}
return $content;
}
These functions are part of a larger class which essentially operates much like Wordpress actions. I.e. I can hook into a portion of content with filtering or such.
Related
So i try to make a hooking API like wordpress add_filter and apply_filters,
So this is my implementation
My problem is that apply_filters does not filter the hook
$hook = new Hook();
$hook->add_filter('filter',function($test) {
return ' stackoverflow';
});
$hook->add_filter('filter',function($test) {
return $test .' world';
},1);
echo $hook->apply_filters('filter','hello');
// Result is hello world
What's wrong with my code, I want to result like this
hello world stackoverflow
For adding filters
public function add_filter(string $tag,mixed $object,int $priority = 10,int $args_limit = 1): void
{
$hooks = static::$hooks;
if(isset($hooks[$tag])) {
static::$hooks[$tag]['sorted'] = false;
static::$hooks[$tag]['priority'][] = $priority;
static::$hooks[$tag]['object'][] = $object;
static::$hooks[$tag]['args_limit'][] = $args_limit;
} else {
static::$hooks[$tag] = [
'sorted' => true,
'priority' => [$priority],
'object' => [$object],
'args_limit' => [$args_limit]
];
}
}
and for applying the filters
public function apply_filters(string $tag,mixed $value,mixed ...$args): mixed
{
$hooks = static::$hooks;
// Shift value to args
array_unshift($args,$value);
$num_args = count($args);
if(isset($hooks[$tag])) {
$hooks = $hooks[$tag];
if(!$hooks['sorted']) {
// Sort filter by priority
array_multisort(
$hooks['priority'],
SORT_NUMERIC,
$hooks['object'],
$hooks['args_limit']
);
$hooks['sorted'] = true;
}
foreach($hooks['object'] as $key => $object) {
$args_limit = $hooks['args_limit'][$key];
if(0 === $args_limit) {
$value = call_user_func($object);
} elseif($args_limit >= $num_args) {
$value = call_user_func_array($object,$args);
} else {
// Slice arguments if not meet from the second statement
$value = call_user_func_array($object,array_slice($args,0,$args_limit));
}
}
}
return $value;
}
So I try to look wordpress core code but the too complicated.
Thanks
Finally solved it! , I just forgot that $value doesn't pass to the callbacks
Here's the fix, for future references
public function apply_filters(string $tag,mixed $value,mixed ...$args): mixed
{
$hooks = static::$hooks;
// +1 for $value parameter
$num_args = count($args) + 1;
if(isset($hooks[$tag])) {
$hooks = $hooks[$tag];
if(!$hooks['sorted']) {
// Sort filter by priority
array_multisort(
$hooks['priority'],
SORT_NUMERIC,
$hooks['object'],
$hooks['args_limit']
);
$hooks['sorted'] = true;
}
foreach($hooks['object'] as $key => $object) {
$args_limit = $hooks['args_limit'][$key];
if(0 === $args_limit) {
$value = call_user_func($object);
} elseif($args_limit >= $num_args) {
$value = call_user_func($object,$value,...$args);
} else {
// Slice arguments if not meet from the second statement
$slice = array_slice($args,0,$args_limit);
$value = call_user_func($object,$value,...$slice);
}
}
}
return $value;
}
I want to create anonymous functions and add them to the hook instead of using defined functions in the hooks.
Error:spl_object_hash() expects exactly 1 parameter, 2 given in D:server\www\deneme\sistem\kanca.php on line 313
Error Problem function benzersiz_Filtre_id() spl_object_hash function
Misuse: kanca_cek("panel_main",function(){ return "a";});
Normal use: kanca_cek("panel_main","db_filter");
function kanca_tak($ad,$fonksiyon,$onem=10,$deger=1){
return self::filtre_ekle($ad,$fonksiyon,$onem,$deger);
}
function kanca_sil($ad,$fonksiyon,$onem=10){
return self::filtre_sil($ad,$fonksiyon,$onem);
}
function tum_kancalari_sil($ad,$onem=false){
return self::tum_filtreleri_sil($ad,$onem);
}
function kanca_sor($ad,$fonksiyon_kontrol=false){
return self::filtre_sor($ad,$fonksiyon_kontrol);
}
function kanca_saydir($ad){
if(!isset($this->islemSayaci) || !isset($this->islemSayaci[$ad]))
return 0;
return $this->islemSayaci[$ad];
}
function islemSayaci($ad,$kanca=false){
$kancaSor=($kanca ? "kanca":"filtre");
if(isset($this->islemSayaci[$ad][$kancaSor]))
$this->islemSayaci[$ad][$kancaSor]++;
else
$this->islemSayaci[$ad][$kancaSor]=1;
}
function kanca_cek($ad,$deger=''){
$depo = array();
$uFv=array();
if (isset($this->filtreler['hepsi'])) {
$this->guncelFiltre[] = $ad;
$depo = func_get_args();
$this->tum_kancalari_cagir($depo);
}
if (!isset($this->filtreler[$ad])) {
if (isset($this->filtreler['hepsi']))
array_pop($this->guncelFiltre);
return;
}
if (!isset($this->filtreler['hepsi']))
$this->guncelFiltre[] = $ad;
if (is_array($deger) && 1 == count($deger) && isset($deger[0]) && is_object($deger[0])) // array(&$this)
$depo[] =& $deger[0];
elseif(!empty($deger))
$depo[] = $deger;
for ($a = 2; $a < func_num_args(); $a++)
$depo[] = func_get_arg($a);
// Sort
if (!isset($this->topluFiltreler[$ad])) {
ksort($this->filtreler[$ad]);
$this->topluFiltreler[$ad] = true;
}
self::islemSayaci($ad,true);
do {
foreach ((array) current($this->filtreler[$ad]) as $yaz){
/**
*#param $uFv değişkeni call_user_func_array fonksiyonunda kullanıcı tanımlı fonksiyona gönderilecek değerleri içerir
*#param accepted_args varsa ve gelen değer eğer dizeyse $uFv ile $yaz["accepted_args"] birleştirir $uFv değişkenine atar.
* #example call_user_func_array gönderilecek değerleri oluşturur.
*/
$uFv=array_slice($depo, 0, (int) $yaz['accepted_args']);
if(isset($yaz["accepted_args"]) && is_array($yaz["accepted_args"]))
$uFv=array_merge($uFv,$yaz["accepted_args"]);
if (isset($yaz['fonksiyon']) && !is_null($yaz['fonksiyon']))
call_user_func_array($yaz["fonksiyon"], $uFv);
// call_user_func_array($yaz['fonksiyon'], array_slice($depo, 0, (int) $yaz['accepted_args']));
}
} while (next($this->filtreler[$ad]) !== false);
array_pop($this->guncelFiltre);
}
function referans_diziyle_kancala($ad,$deger){
if (isset($this->filtreler['hepsi'])) {
$this->guncelFiltre[] = $ad;
$depo = func_get_args();
$this->tum_kancalari_cagir($depo);
}
if (!isset($this->filtreler[$ad])) {
if (isset($this->filtreler['hepsi']))
array_pop($this->guncelFiltre);
return;
}
if (!isset($this->filtreler['hepsi']))
$this->guncelFiltre[] = $tag;
// Sort
if (!isset($this->topluFiltreler[$ad])) {
ksort($this->filtreler[$ad]);
$this->topluFiltreler[$ad] = true;
}
reset($this->filtreler[$tag]);
do {
foreach ((array) current($this->filtreler[$ad]) as $yaz)
if (isset($yaz['fonksiyon']) && !is_null($yaz['fonksiyon']))
call_user_func_array($yaz['fonksiyon'], array_slice($deger, 0, (int) $yaz['accepted_args']));
} while (next($this->filtreler[$ad]) !== false);
array_pop($this->guncelFiltre);
}
function filtre_ekle($ad,$fonksiyon,$onem,$deger=1,$sadeceKelime=0){
$fk=($sadeceKelime ? $ad."_".password_hash(rand(0,10000),PASSWORD_DEFAULT):$fonksiyon);
$cId=self::benzersiz_Filtre_id($ad,$fk,$onem);
if($sadeceKelime){
$this->filtreler[$ad][$onem][$cId]=array(
'deger'=>$fonksiyon,
'accepted_args'=>$deger,
'sK'=>$sadeceKelime);
}
else{
$this->filtreler[$ad][$onem][$cId]=array(
'fonksiyon'=>$fonksiyon,
'accepted_args'=>$deger,
'sK'=>$sadeceKelime);
}
unset($this->topluFiltreler[$ad]);
}
function filtre_sil($ad,$fonksiyon,$onem=10){
$fSil = self::benzersiz_Filtre_id($ad, $fonksiyon, $onem);
$varMi = isset($this->filtreler[$ad][$onem][$fSil]);
if (true === $varMi) {
unset($this->filtreler[$ad][$onem][$fSil]);
if (empty($this->filtreler[$ad][$onem]))
unset($this->filtreler[$ad][$onem]);
unset($this->topluFiltreler[$ad]);
}
return $varMi;
}
function tum_filtreleri_sil($ad,$onem=false){
if (isset($this->filtreler[$ad])) {
if (false !== $onem && isset($this->filtreler[$ad][$onem]))
unset($this->filtreler[$ad][$onem]);
else
unset($this->filtreler[$ad]);
}
if (isset($this->topluFiltreler[$ad]))
unset($this->topluFiltreler[$ad]);
return true;
}
function filtre_sor($ad,$fonksiyon_kontrol=false){
$sor=!empty($this->filtreler[$ad]);
if($fonksiyon_kontrol===false || $sor==false)
return $sor;
if(!$idSor=self::benzersiz_Filtre_id($ad,$fonksiyon_kontrol,false))
return false;
foreach ((array) array_keys($this->filtreler[$ad]) as $onem) {
if (isset($this->filtreler[$ad][$onem][$idSor]))
return $onem;
}
return false;
}
function guncel_filtre(){
return end($this->guncelFiltre);
}
public function filtrele($ad, $deger)
{
$depo = array();
$dondur=null;
$uFv=array();//call_user_func_array gönderilen Dizisi
// Do 'all' actions first
if(isset($this->filtreler["all"]))
{
$this->guncelFiltre=$ad;
$depo=func_get_arg();
$this->tum_kancalari_cagir($depo);
}
if(!isset($this->filtreler[$ad]))
{
if(isset($this->filtreler["all"]))
array_pop($this->guncelFiltre);
return $deger;
}
if (!isset($this->filtreler['hepsi']))
$this->guncelFiltre[] = $ad;
// Sort
if (!isset($this->topluFiltreler[$ad])) {
ksort($this->filtreler[$ad]);
$this->topluFiltreler[$ad] = true;
}
if (empty($depo))
$depo = func_get_args();
$keySifirla = array_map('array_values', $this->filtreler[$ad]);
do {
$conDizi=(is_array($keySifirla) ? $keySifirla:(array) $KXC);
foreach (current($conDizi) as $kx=>$yaz){
if (isset($yaz['fonksiyon']) && !is_null($yaz['fonksiyon'])) {
$depo[1] = $deger;
}
if(isset($yaz["deger"])){
if(is_array($yaz["deger"])){
foreach($yaz["deger"] as $yK)
$deger[]=$yK;
}else{
$deger=$yaz["deger"];
}
}else{
if(is_callable($yaz["fonksiyon"]) && $yaz["fonksiyon"] instanceof Closure) {
$yaz["fonksiyon"]();
}
elseif(function_exists($yaz["fonksiyon"])){
/**
*#param $uFv değişkeni call_user_func_array fonksiyonunda kullanıcı tanımlı fonksiyona gönderilecek değerleri içerir
*#param accepted_args varsa ve gelen değer eğer dizeyse $uFv ile $yaz["accepted_args"] birleştirir $uFv değişkenine atar.
* #example call_user_func_array gönderilecek değerleri oluşturur.
*/
$uFv=array_slice($depo, 1, (int) $yaz['accepted_args']);
if(isset($yaz["accepted_args"]) && is_array($yaz["accepted_args"]))
$uFv=array_merge($uFv,$yaz["accepted_args"]);
$deger = call_user_func_array($yaz["fonksiyon"], $uFv);
}
else{
hata_ekle($yaz["fonksiyon"]." fonksiyonu bulunamadı.","hata");
return false;
}
}
}
} while (next($keySifirla) !== false);
array_pop($this->guncelFiltre);
self::islemSayaci($ad);
return $deger;
}
function referans_diziyle_filtrele($ad,$deger){
// Do 'all' actions first
if (isset($this->filtrele['all'])) {
$this->guncelFiltre[] = $ad;
$depo = func_get_args();
$this->tum_kancalari_cagir($depo);
}
if (!isset($this->filtrele[$ad])) {
if (isset($this->filtrele['all']))
array_pop($this->guncelFiltre);
return $deger[0];
}
if (!isset($this->filtrele['all']))
$this->guncelFiltre[] = $ad;
// Sort
if (!isset($this->topluFiltreler[$ad])) {
ksort($this->filtrele[$ad]);
$this->topluFiltreler[$ad] = true;
}
reset($this->filtrele[$ad]);
do {
foreach ((array) current($this->filtrele[$ad]) as $yaz)
if (isset($yaz['fonksiyon']) && !is_null($yaz['fonksiyon']))
$deger[0] = call_user_func_array($yaz['fonksiyon'], array_slice($deger, 0, (int) $deger['accepted_args']));
} while (next($this->filtrele[$ad]) !== false);
array_pop($this->guncelFiltre);
return $depo[0];
}
public function tum_kancalari_cagir($deger)
{
reset($this->filtreler['hepsi']);
do {
foreach ((array) current($this->filtreler['hepsi']) as $yaz)
if (isset($yaz['fonksiyon']) && !is_null($yaz['fonksiyon']))
call_user_func_array($yaz['fonksiyon'], $depo);
} while (next($this->filtreler['hepsi']) !== false);
}
function dumps(){
echo "<pre>";
print_r($this);
echo "</pre>";
}
function benzersiz_Filtre_id($ad,$fonksiyon,$onem){
static $idSaydir=0;
if(is_string($fonksiyon))
return $fonksiyon;
if(is_object($fonksiyon))
$fonksiyon=array($fonksiyon,'');
else
$fonksiyon=(array) $fonksiyon;
if(is_object($fonksiyon[0]))
{
if(function_exists('spl_object_hash')){
return spl_object_hash($fonksiyon[0],$fonksiyon[1]);
}else{
$nesneId=get_class($fonksiyon[0]).$fonksiyon[1];
if (!isset($fonksiyon[0]->filter_id)) {
if (false === $onem)
return false;
$nesneId .= isset($this->filtreler[$ad][$onem]) ? count((array) $$this->filtreler[$ad][$onem]) : $idSaydir;
$fonksiyon[0]->filter_id = $idSaydir;
++$idSaydir;
} else {
$nesneId .= $fonksiyon[0]->filter_id;
}
return $nesneId;
}
} else if (is_string($fonksiyon[0])) {
if(count($fonksiyon)>=2)
return $fonksiyon[0] . $fonksiyon[1];
else
return $fonksiyon[0];
}
}
}
Problem Function 313 line code
if(function_exists('spl_object_hash')){
return spl_object_hash($fonksiyon[0],$fonksiyon[1]);
}else{
$nesneId=get_class($fonksiyon[0]).$fonksiyon[1];
the function from which the error was received
function benzersiz_Filtre_id($ad,$fonksiyon,$onem){
static $idSaydir=0;
if(is_string($fonksiyon))
return $fonksiyon;
if(is_object($fonksiyon))
$fonksiyon=array($fonksiyon,'');
else
$fonksiyon=(array) $fonksiyon;
if(is_object($fonksiyon[0]))
{
if(function_exists('spl_object_hash')){
return spl_object_hash($fonksiyon[0],$fonksiyon[1]);
}else{
$nesneId=get_class($fonksiyon[0]).$fonksiyon[1];
if (!isset($fonksiyon[0]->filter_id)) {
if (false === $onem)
return false;
$nesneId .= isset($this->filtreler[$ad][$onem]) ? count((array) $$this->filtreler[$ad][$onem]) : $idSaydir;
$fonksiyon[0]->filter_id = $idSaydir;
++$idSaydir;
} else {
$nesneId .= $fonksiyon[0]->filter_id;
}
return $nesneId;
}
} else if (is_string($fonksiyon[0])) {
if(count($fonksiyon)>=2)
return $fonksiyon[0] . $fonksiyon[1];
else
return $fonksiyon[0];
}
}
As documented spl_object_hash requires only one argument.
So the part you are using is wrong
if(function_exists('spl_object_hash')){
return spl_object_hash($fonksiyon[0],$fonksiyon[1]);
}else{
$nesneId=get_class($fonksiyon[0]).$fonksiyon[1];
}
As you want the ID (hash) of one object, I suppose you mean
return spl_object_hash($fonksiyon);
// or
return spl_object_hash($fonksiyon[0]);
You can remove the function_exists part, because SPL is part of PHP since 5.0.
I'm trying to load a website url from a textfile, then unset this string from an array and pick a random website from the array.
But once I try to access the array from my function the array would return NULL, does someone know where my mistake is located at?
My current code looks like the following:
<?php
$activeFile = 'activeSite.txt';
$sites = array(
'http://wwww.google.com',
'http://www.ebay.com',
'http://www.icloud.com',
'http://www.hackforums.net',
'http://www.randomsite.com'
);
function getActiveSite($file)
{
$activeSite = file_get_contents($file, true);
return $activeSite;
}
function unsetActiveSite($activeSite)
{
if(($key = array_search($activeSite, $sites)) !== false)
{
unset($sites[$key]);
return true;
}
else
{
return false;
}
}
function updateActiveSite($activeFile)
{
$activeWebsite = getActiveSite($activeFile);
if(!empty($activeWebsite))
{
$unsetActive = unsetActiveSite($activeWebsite);
if($unsetActive == true)
{
$randomSite = $sites[array_rand($sites)];
return $randomSite;
}
else
{
echo 'Could not unset the active website.';
}
}
else
{
echo $activeWebsite . ' did not contain any active website.';
}
}
$result = updateActiveSite($activeFile);
echo $result;
?>
$sites is not avaliable in unsetActiveSite function you need to create a function called "getSites" which return the $sites array and use it in unsetActiveSite
function getSites(){
$sites = [
'http://wwww.google.com',
'http://www.ebay.com',
'http://www.icloud.com',
'http://www.hackforums.net',
'http://www.randomsite.com'
];
return $sites;
}
function unsetActiveSite($activeSite)
{
$sites = getSites();
if(($key = array_search($activeSite, $sites)) !== false)
{
unset($sites[$key]);
return true;
}
else
{
return false;
}
}
I am trying to port my web app from laravel 4 to 5 but I am having issues in that one of my model classes is not found.
I have tried to utilize namespacing and have the following my Models which are located locally C:\xampp\htdocs\awsconfig\app\Models
the file which the error appears in looks like
<?php
use App\Models\SecurityGroup;
function from_camel_case($input)
{
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
$ret = $matches[0];
foreach ($ret as &$match)
{
$match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
}
return implode('_', $ret);
}
$resource_types = array();
$resource_types['AWS::EC2::Instance'] = 'EC2Instance';
$resource_types['AWS::EC2::NetworkInterface'] = 'EC2NetworkInterface';
$resource_types['AWS::EC2::VPC'] = 'VPC';
$resource_types['AWS::EC2::Volume'] = 'Volume';
$resource_types['AWS::EC2::SecurityGroup'] = 'SecurityGroup';
$resource_types['AWS::EC2::Subnet'] = 'Subnet';
$resource_types['AWS::EC2::RouteTable'] = 'RouteTable';
$resource_types['AWS::EC2::EIP'] = 'EIP';
$resource_types['AWS::EC2::NetworkAcl'] = 'NetworkAcl';
$resource_types['AWS::EC2::InternetGateway'] = 'InternetGateway';
$accounts = DB::table('aws_account')->get();
$account_list = array();
foreach(glob('../resources/sns messages/*.json') as $filename)
{
//echo $filename;
$data = file_get_contents($filename);
if($data!=null)
{
$decoded=json_decode($data,true);
if(isset($decoded["Message"]))
{
//echo "found message<br>";
$message= json_decode($decoded["Message"]);
if(isset($message->configurationItem))
{
// echo"found cfi<br>";
$insert_array = array();
$cfi = $message->configurationItem;
switch ($cfi->configurationItemStatus)
{
case "ResourceDiscovered":
//echo"found Resource Discovered<br>";
if (array_key_exists($cfi->resourceType,$resource_types))
{
//var_dump($cfi->resourceType);
$resource = new $resource_types[$cfi->resourceType];
foreach ($cfi->configuration as $key => $value)
{
if (in_array($key,$resource->fields))
{
$insert_array[from_camel_case($key)] = $value;
}
}
$resource->populate($insert_array);
if (!$resource->checkExists())
{
$resource->save();
if(isset($cfi->configuration->tags))
{
foreach ($cfi->configuration->tags as $t )
{
$tag= new Tag;
$tag->resource_type = "instance";
$tag->resource_id = $resource->id;
$tag->key = $t->key;
$tag->value = $t->value;
$tag->save();
/*if(isset($cfi->awsAccountId))
{
foreach ($accounts as $a)
{
$account_list = $a->account_id;
}
if (!in_array($account_id,$account_list))
{
$account_id = new Account;
$account_id->aws_account_id = $cfi->awsAccountId;
$account_list[] = $account_id;
$account_id->save();
}
} */
}
}
}
}
else
{
echo "Creating ".$cfi["resourceType"]." not yet supported<br>";
}
break;
case 'ResourceDeleted':
// echo"found Resource Deleted<br>";
//ITEM DELETED
if (array_key_exists($cfi->resourceType,$resource_types))
{
//var_dump($cfi->resourceType);
$resource = new $resource_types[$cfi->resourceType];
if ($resource->checkExists($cfi->resourceId))
{
$resource->delete();
if( isset($cfi->configuration->tags))
{
foreach ($cfi->configuration->tags as $t )
{
$tag= new Tag;
$tag->resource_type = "instance";
$tag->resource_id = $resource->id;
$tag->key = $t->key;
$tag->value = $t->value;
if ($tag->checkExists($cfi->configuration->tags))
{
$tag->delete();
}
}
}
}
}
else
{
echo "Deleting ".$cfi["resourceType"]." not yet supported<br>";
}
break;
case 'OK':
//echo"found Resource OK<br>";
//ITEM UPDATED
if (array_key_exists($cfi->resourceType, $resource_types))
{
//var_dump($cfi->resourceType);
$resource = new $resource_types[$cfi->resourceType];
if ($resource->checkExists($cfi->resourceId))
{
foreach ($cfi->configuration as $key => $value)
{
if (in_array($key,$resource->fields))
{
$update_array[from_camel_case($key)] = $value;
}
}
$resource->populate($update_array);
$resource->save();
}
}
else
{
echo "Updating ".$cfi["resourceType"]." not yet supported<br>";
}
break;
default:
echo "Status ".$cfi['configurationItemStatus']." not yet supported<br>";
break;
}
}
}
}
}
and the corresponding model whose class cannot be found looks like :
<?php namespace App\Models;
use Eloquent;
class SecurityGroup extends Eloquent
{
protected $table = 'security_group';
public $timestamps = false;
protected $guarded = array('id');
public $fields = array('groupId',
'groupName',
'description',
'ownerId'
);
public function checkExists()
{
return self::where('group_id', $this->group_id)->first();
}
public function populate($array)
{
foreach ($array as $k => $v)
{
$this->$k = $v;
}
}
}
I am lost as to what is causing the problem I don't see any typos but then again who knows as always thanks for any help given.
to solve the resource type needs the full namespace declaration
I have checked the memory whilst sending and receiving data over one connection, and I appear to be correctly clearing variables, as the memory returns to its previous value.
But for some reason if I make a new connection, then close the connection, memory is leaked. I believe the problem may be occurring when a socket is accepted.
I am using PHP 5.2.10
Hopefully one of you can find the time to have a play with the source and figure out where its gone wrong. Thanks in advance
<?php
Class SuperSocket
{
var $listen = array();
var $status_listening = FALSE;
var $sockets = array();
var $event_callbacks = array();
var $recvq = 1;
var $parent;
var $delay = 100; // 10,000th of a second
var $data_buffer = array();
function SuperSocket($listen = array('127.0.0.1:123'))
{
$listen = array_unique($listen);
foreach ($listen as $address)
{
list($address, $port) = explode(":", $address, 2);
$this->listen[] = array("ADDR" => trim($address), "PORT" => trim($port));
};
}
function start()
{
if ($this->status_listening)
{
return FALSE;
};
$this->sockets = array();
$cursocket = 0;
foreach ($this->listen as $listen)
{
if ($listen['ADDR'] == "*")
{
$this->sockets[$cursocket]['socket'] = socket_create_listen($listen['PORT']);
$listen['ADDR'] = FALSE;
}
else
{
$this->sockets[$cursocket]['socket'] = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
};
if ($this->sockets[$cursocket]['socket'] < 0)
{
return FALSE;
};
if (#socket_bind($this->sockets[$cursocket]['socket'], $listen['ADDR'], $listen['PORT']) < 0)
{
return FALSE;
};
if (socket_listen($this->sockets[$cursocket]['socket']) < 0)
{
return FALSE;
};
if (!socket_set_option($this->sockets[$cursocket]['socket'], SOL_SOCKET, SO_REUSEADDR, 1))
{
return FALSE;
};
if (!socket_set_nonblock($this->sockets[$cursocket]['socket']))
{
return FALSE;
};
$this->sockets[$cursocket]['info'] = array("ADDR" => $listen['ADDR'], "PORT" => $listen['PORT']);
$this->sockets[$cursocket]['channels'] = array();
$this->sockets[$cursocket]['id'] = $cursocket;
$cursocket++;
};
$this->status_listening = TRUE;
}
function new_socket_loop(&$socket)
{
$socket =& $this->sockets[$socket['id']];
if ($newchannel = #stream_socket_accept($socket['socket'], 0));//#socket_accept($socket['socket']))
{
socket_set_nonblock($newchannel);
$socket['channels'][]['socket'] = $newchannel;
$channel = array_pop(array_keys($socket['channels']));
$this->remote_address($newchannel, $remote_addr, $remote_port);
$socket['channels'][$channel]['info'] = array('ADDR' => $remote_addr, 'PORT' => $remote_port);
$event = $this->event("NEW_SOCKET_CHANNEL");
if ($event)
$event($socket['id'], $channel, $this);
};
}
function endswith($string, $test) {
$strlen = strlen($string);
$testlen = strlen($test);
if ($testlen > $strlen) return false;
return substr_compare($string, $test, -$testlen) === 0;
}
function recv_socket_loop(&$socket)
{
$socket =& $this->sockets[$socket['id']];
foreach ($socket['channels'] as $channel_id => $channel)
{
unset($buffer);#Flush buffer
$status = #socket_recv($channel['socket'], $buffer, $this->recvq, 0);
if ($status === 0 && $buffer === NULL)
{
$this->close($socket['id'], $channel_id);
}
elseif (!($status === FALSE && $buffer === NULL))
{
$sockid = $socket['id'];
if(!isset($this->data_buffer[$sockid]))
$this->data_buffer[$sockid]='';
if($buffer!="\r"&&$buffer!="\n")
{
//Putty ends with \r\n
$this->data_buffer[$sockid].=$buffer;
}
else if($buffer!="\n") //ignore the additional newline char \n
{
$event = $this->event("DATA_SOCKET_CHANNEL");
if ($event)
$event($socket['id'], $channel_id, $this->data_buffer[$sockid], $this);
unset($this->data_buffer[$sockid]);
}
};
}
}
function stop()
{
$this->closeall();
$this->status_listening = FALSE;
foreach ($this->sockets as $socket_id => $socket)
{
socket_shutdown($socket['socket']);
socket_close($socket['socket']);
};
$event = $this->event("SERVER_STOP");
if ($event)
$event($this);
}
function closeall($socket_id = NULL)
{
if ($socket_id === NULL)
{
foreach ($this->sockets as $socket_id => $socket)
{
foreach ($socket['channels'] as $channel_id => $channel)
{
$this->close($socket_id, $channel_id);
}
}
}
else
{
foreach ($this->sockets[$socket_id]['channels'] as $channel_id => $channel)
{
$this->close($socket_id, $channel_id);
};
};
}
function close($socket_id, $channel_id)
{
unset($this->data_buffer[$socket_id]); //clear the sockets data buffer
$arrOpt = array('l_onoff' => 1, 'l_linger' => 1);
#socket_shutdown($this->sockets[$socket_id]['channels'][$channel_id]['socket']);
#socket_close($this->sockets[$socket_id]['channels'][$channel_id]['socket']);
$event = $this->event("LOST_SOCKET_CHANNEL");
if ($event)
$event($socket_id, $channel_id, $this);
}
function loop()
{
while ($this->status_listening)
{
usleep($this->delay);
foreach ($this->sockets as $socket)
{
$this->new_socket_loop($socket);
$this->recv_socket_loop($socket);
};
$event = $this->event("END_SOCKET_CHANNEL");
if ($event)
$event($this);
};
}
function write($socket_id, $channel_id, $buffer)
{
#socket_write($this->sockets[$socket_id]['channels'][$channel_id]['socket'], $buffer);
#socket_write($this->sockets[$socket_id]['channels'][$channel_id]['socket'], 'Server memory usage: '.memory_get_usage().'/'.memory_get_peak_usage(true)."\r\n");
}
function get_channel_info($socket_id, $channel_id)
{
return $this->sockets[$socket_id]['channels'][$channel_id]['info'];
}
function get_socket_info($socket_id)
{
$socket_info = $this->sockets[$socket_id]['info'];
if (empty($socket_info['ADDR']))
{
$socket_info['ADDR'] = "*";
};
return $socket_info;
}
function get_raw_channel_socket($socket_id, $channel_id)
{
return $this->sockets[$socket_id]['channels'][$channel_id]['socket'];
}
function remote_address($channel_socket, &$ipaddress, &$port)
{
socket_getpeername($channel_socket, $ipaddress, $port);
}
function event($name)
{
if (isset($this->event_callbacks[$name]))
return $this->event_callbacks[$name];
}
function assign_callback($name, $function_name)
{
$this->event_callbacks[$name] = $function_name;
}
};
?>
Server.php
include("supersocket.class.php");
function startswith($string, $test) {
return strpos($string, $test, 0) === 0;
}
function newdata($socket_id, $channel_id, $buffer, &$server)
{
//$server->write($socket_id, $channel_id, ">".$buffer."\r\n");
if($buffer=="STOP")
{
$server->stop();
}
else if($buffer=="DATETIME")
{
$server->write($socket_id, $channel_id, ">".date("dmYHis")."\r\n");
}
else
{
$server->write($socket_id, $channel_id, ">BAD\r\n");
}
};
function newclient($socket_id, $channel_id, &$server)
{
$server->write($socket_id, $channel_id, "HEADER\n\r");
}
$socket = new SuperSocket(array('127.0.0.1:12345'));
$socket->assign_callback("DATA_SOCKET_CHANNEL", "newdata");
$socket->assign_callback("NEW_SOCKET_CHANNEL", "newclient");
$socket->start();
//set_time_limit(60*2);
set_time_limit(60*60*24*5); //5 days
$socket->loop();
Edit: sorry you might need to change the socket accept back to:
if ($newchannel = #socket_accept($socket['socket']))
then close the connection, memory is leaked
This is a tricky one - even the standard reference counting garbage collector only kicks in at intervals which are difficult to predict. Calling gc_collect_cycles() should trigger the gc though. Try calling that whenever you close a connection and see if it makes a difference.
If you're still seeing problems - then check if you've got the cyclic reference counter compiled in - if not, then get it.
The Channel array was never removed upon closing the connection, surprised no one picked up on this. Memory usage is now super tight.
unset($this->sockets[$socket_id]['channels'][$channel_id]);
But it does mean that any event for LOST_SOCKET_CHANNEL is pretty useless for the time being.
Will accept my own answer when stack over flow allows. Thanks for all your help ppl .. i guess..