I am trying to write a simple application with wxPHP that pings IPs from a file using exec('ping')
command.
I want the results to show up in the GUI one by one as they get pinged in the background so I'm doing the exec('ping')
command in a thread.
But I get very strange errors and behavior. The problem is I can't reproduce the errors. Sometimes the program works totally fine. Sometimes it crashes in the thread. Sometimes it crashes when it is sending the event. etc.
Here are the errors I get when I run the program from command line:
C:\Users\SH\Desktop>wxphp pinger.wxphp
PHP Notice: Undefined property: wxHtmlWindow::$parent in Unknown on line 0
PHP Fatal error: Call to a member function setPingResults() on null in Unknown
on line 0
C:\Users\SH\Desktop>wxphp pinger.wxphp
PHP Notice: Undefined property: wxHtmlWindow::$parent in Unknown on line 0
PHP Fatal error: Call to a member function setPingResults() on null in Unknown
on line 0
C:\Users\SH\Desktop>wxphp pinger.wxphp
PHP Notice: Undefined property: wxHtmlWindow::$parent in Unknown on line 553649674
PHP Fatal error: Call to a member function setPingResults() on null in Unknown
on line 553649674
And this is my code:
<?php
if(!extension_loaded('wxwidgets'))
{
dl('wxwidgets.' . PHP_SHLIB_SUFFIX);
}
define('EVT_PINGDONE',wxNewEventType());
class myPing extends wxThread
{
function __construct($parent)
{
parent::__construct(wxTHREAD_JOINABLE);
$this->parent = $parent;
}
function Entry()
{
$addresses = file($this->parent->btnBrowse->GetPath(),FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES);
foreach($addresses as $k => $address){
$results = exec("ping $address");
$this->parent->setPingResults($results);
$evt = new wxCommandEvent(EVT_PINGDONE);
$this->parent->QueueEvent($evt);
}
$this->parent->onThreadDone();
return;
}
}
class mythFrame extends wxFrame {
function __construct( $parent=null ){
parent::__construct ( $parent, wxID_ANY, 'Pinger', wxDefaultPosition, new wxSize( 600,400 ), wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
$this->SetSizeHints( wxDefaultSize, wxDefaultSize );
$bSizer2 = new wxBoxSizer( wxHORIZONTAL );
$this->button = new wxButton( $this, wxID_ANY, "Ping", wxDefaultPosition, new wxSize(300, 40), 0 );
$bSizer2->Add($this->button, 0, wxALL|wxEXPAND, 5);
$bSizer1 = new wxBoxSizer( wxVERTICAL );
$this->btnBrowse = new wxFilePickerCtrl( $this, wxID_ANY, 'C:\Users\SH\Desktop\stuff\servers.txt', "Select a file", "*.*", wxDefaultPosition, wxDefaultSize, wxFLP_DEFAULT_STYLE );
$bSizer1->Add( $this->btnBrowse, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 );
$this->html = new wxHtmlWindow( $this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
$bSizer1->Add( $this->html, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 );
$bSizer1->Add( $bSizer2, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
$this->SetSizer( $bSizer1 );
$this->Layout();
$this->Centre( wxBOTH );
// Connect Events
$this->button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, array($this, "hndlrButton") );
$this->Connect(wxEVT_TIMER, array($this, "onTimer"));
$this->Connect(EVT_PINGDONE, array($this, 'updateText'));
$this->pingThread = new myPing($this);
$this->m_timer = new wxTimer($this);
$this->pingResults = '';
}
function updateText($event){
$this->html->AppendToPage($this->pingResults.'<br>');
}
function onTimer(){
if($this->threadDone == true){
$this->m_timer->Stop();
$this->button->Enable();
$this->btnBrowse->Enable();
$this->html->AppendToPage('<br>Finished.<hr>');
while($this->pingThread->IsRunning()){}
$this->pingThread->Delete();
$this->pingThread = new myPing($this);
}
}
function onThreadDone(){
$this->threadDone = true;
}
function setPingResults($results){
$this->pingResults = $results;
}
function hndlrButton( $event ){
$this->threadDone = false;
$this->m_timer->start(3000);
$this->button->Disable();
$this->btnBrowse->Disable();
$this->pingThread->Create();
$this->pingThread->Run();
}
}
$myFrame = new mythFrame();
$myFrame->show();
wxEntry();
?>
And this is the errors I get in windows error log:
Faulting application name: wxphp.exe, version: 5.6.9.0, time stamp: 0x55765568
Faulting module name: ntdll.dll, version: 6.1.7601.18247, time stamp: 0x521eaf24
Exception code: 0xc0000005
Fault offset: 0x0000000000052f86
Faulting process id: 0x3c4
Faulting application start time: 0x01d0b6675e88094f
Faulting application path: C:\Program Files\wxPHP\php\wxphp.exe
Faulting module path: C:\Windows\SYSTEM32\ntdll.dll
Report Id: 9cd6fe5e-225a-11e5-b316-f46d04f70903
Faulting module changes depending on whether i call php functions or call exec()
in the thread Entry()
. But the exception code is always 0xc0000005
.
One weird thing that is consistent in errors is errors like
Undefined property wxHtmlWindow::$parent
If you read the code you realize that there is no such call at all. Actually $parent
is only accessed in the thread. I have got similar errors with other functions in the thread. It seems like the application doesn't realize it is in the thread and $this
in the thread points to the main frame object.
I guess something is terribly wrong with my code or maybe with wxPHP. This program was not working last night, then started working this morning. Then I added an icon and some background colors to it and it suddenly is giving me errors again.
Other info
Doesn't work on:
Windows 7-64bit - wxphp-3.0.2.0-php5.6-x64.exe
Windows 7-32bit - wxphp-3.0.2.0-php5.4-x86
- The example
thread.wxphp
application bundled with the wxPHP package doesn't work either. - However both my code and the example app work fine on Linux (
Linux Mint-32bit - php5-wxwidgets_3.0.2.0_i386
). - When I remove both
exec()
andQueueEvent()
from the threadEntry()
I don't get any errors.
Does anyone have any idea what's going on here?