-
Posts
4,704 -
Joined
-
Last visited
-
Days Won
179
Community Answers
-
kicken's post in Set array values and preserve keys was marked as the answer
Do you want to keep the keys, but reset all their values to empty array's? Not really sure what you're asking/trying to do.
If you just want the keys + empty array values then you could just do this:
$arr2 = array_fill_keys(array_keys($arr), []); -
kicken's post in Dice Roller worked in PHP5, but won't in PHP7 environment was marked as the answer
From the manual page for eregi:
You need to update your code to the alternative.
Or preferably, use a library for your mailing needs such as PHPMailer or SwiftMailer which will properly handle this task.
-
kicken's post in why 'i' means minuites in PHP date format? was marked as the answer
If the first letter of a word can't be used as a shortcut because it's taken by something else, most people just move on to the second, then third, etc until one is available.
So, minutes.
-
kicken's post in array_filter not === with $varible only with text entry was marked as the answer
You're not showing $variphone being defined there anywhere. If it's not defined within your function then it won't exist. PHP doesn't inherit variables from outer scopes automatically like some other languages. You can import variables you need using a use statement, as demonstrated in ignace's example.
-
kicken's post in Best way to record a users input was marked as the answer
Just pull the user id from your session data and use that in your query. So your original code sample would be for example:
session_start();. $usr_id = $_SESSION['usr_id']; $client_title =$_POST['client_title']; $client_name =$_POST['client_name']; $client_contact =$_POST['client_contact']; $client_email =$_POST['client_email']; $notes =$_POST['notes']; $sql = "INSERT INTO firsts (usr_id, client_title, client_name, client_contact, client_email, notes ) VALUES ('$usr_id', '$client_title' , '$client_name' ,'$client_contact' ,'$client_email' ,'$notes' )"; Before you get much further in your project, you really need to do some reading on SQL Injection and prevent it. I'd suggest you learn how to use the PDO API and parameter binding. -
kicken's post in Another, sigh, "unexpected end of file" error was marked as the answer
Some of your quote marks are of the "smart quotes" variety which won't work. Replace them with standard ascii quotes.
-
kicken's post in PHP Export to multiple excel file was marked as the answer
As far as generating the "excel" files, if you don't need any of the fancy features like multiple-sheets, formatting, etc then I generally find it to be easiest to just generate a CSV file. The file type is generally mapped to a user's spreadsheet program (be that excel, open office, whatever) and is easy to generate/inspect.
<?php if(isset($_GET['groupname'], $_GET['decks'], $_GET['rows'])){ $groupname = $_GET['groupname']; $decks = $_GET['decks']; $rows = $_GET['rows']; $pickdeckrows = $rows/$decks; //for($i=1; $i<=$decks; $i++){ $stmt = $dbconnect->prepare("SELECT v.decknumber, v.vtext FROM decks v WHERE v.groupname =:groupname LIMIT :pickdeckrows"); $stmt->bindValue(':groupname', $groupname); $stmt->bindValue(':pickdeckrows', $pickdeckrows); $stmt->execute(); ob_end_clean(); $output = fopen('php://memory', 'w+'); $length = fputcsv($output, [ 'GroupId' , 'Text' ]); while($row = $stmt -> fetch()){ $length += fputcsv($output, [ $row["decknumber"] , $row["vtext"] ]); } header('Content-Type: text/csv'); header('Content-length: '.$length); header('Content-Disposition: attachment; filename='.$groupname.'deck.csv'); rewind($output); fpassthru($output); fclose($output); $stmtdelete = $dbconnect->prepare("DELETE FROM decks WHERE groupname =:groupname LIMIT :pickdeckrows"); $stmtdelete -> bindValue(':groupname', $groupname); $stmtdelete -> bindValue(':pickdeckrows', $pickdeckrows); $stmtdelete -> execute(); //} } And as mentioned, if you need to provide multiple files in a single request, package them up into an archive. then serve that file. -
kicken's post in PHP PDO Create Temporary Table Error was marked as the answer
If you're dealing with a relatively small number of rows like you say (300-ish that you need to keep track of) then just store the row ID's into either your session variable or a hidden form input and re-select them in the second step.
If you're dealing with larger data sets you can create a persistent table to use as scratch space. You can create it as a memory table so it functions like a temporary table.
CREATE TABLE randomsample ( `id` int(11) NOT NULL AUTO_INCREMENT, `groupid` int(11) NOT NULL, `groupname` varchar(100), `text` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MEMORY You only need to make the table once, so you'd take the create out of your script. Instead just dump your data into it at the first step, then delete it after you're done at the last step. -
kicken's post in Using upsert with multiple unique index/columns was marked as the answer
You'd write a query that gives you the results you want and use grouping to get it aggregated by day or whatever you need. Then to make it easier to manage/use you can create a view using the query.
It sounds like your current query gives you what you want so you'd just turn that into a view, probably without the date filter in the WHERE clause though. Eg:
CREATE VIEW daily_report SELECT c.extension as Extension , RESPONSIBLEUSEREXTENSIONID as ExtID , sum(Duration) as Total_Talk_Time_seconds , round(sum(Duration) / 60,2) as Total_Talk_Time_minutes , sum(if(LEGTYPE1 = 1,1,0)) as Total_Outbound , sum(if(LEGTYPE1 = 2,1,0)) as Total_Inboundambition_test , sum(if(Answered = 1,0,1)) as Missed_Calls , count(DISTINCT b.NOTABLECALLID) as Total_Calls , DATE(b.ts) as reportDate FROM cdrdb.session a LEFT JOIN cdrdb.callsummary b ON a.NOTABLECALLID = b.NOTABLECALLID LEFT join cdrdb.mxuser c ON a.RESPONSIBLEUSEREXTENSIONID = c.EXTENSIONID WHERE c.extension IN (7295,7306,7218,7247,7330,7000,7358) GROUP BY c.extension Then you use that to get your details for whatever day using something like
SELECT * FROM daily_report WHERE reportDate >= curdate() -
kicken's post in Rewrite based on url var was marked as the answer
Something like this probably:
RewriteCond %{QUERY_STRING} ^make=(.*)$ [NC] RewriteRule ^$ /vehicle [NC,L,R=301] The problem with using (.*) is that it will match /vehicle. You want the rule to only apply when the request is against the root (I'm assuming). If you need it against anything but /vehicle then try:
RewriteCond %{QUERY_STRING} ^make=(.*)$ [NC] RewriteRule !^vehicle$ /vehicle [NC,L,R=301] -
kicken's post in Correct User-Friendly URL Appears, But Bad GET Value Is Processed was marked as the answer
Query strings are not part of the URL when it comes to matching with RewriteRule. To match the query string you need to use RewriteCond on the %{QUERY_STRING} variable.
Also rules are proccessed in order, so if you have overlapping matches you need to ensure to order them most-specific to least-specific. So you want to match against fr/member-subscription.html?country first, then if that fails match against fr/member-subscription.html. Since there's no need for them to chain together either, stick a LAST flag on them also to prevent further processing.
RewriteCond %{QUERY_STRING} country=(.*) RewriteRule fr/member-subscription.html fr/newmember.php?ctry_data=%1 [L] RewriteRule fr/member-subscription.html fr/newmember.php?id=newmember [L] -
kicken's post in Why does socket server no longer accept remote connections? was marked as the answer
Your symptoms all point to a firewall blocking traffic. Sounds like you didn't disable it properly or perhaps you have a second one somewhere.
-
kicken's post in Will this work as a websocket server? was marked as the answer
No, it's not.
Websocket is a specific protocol. You have to implement that protocol if you want a Websocket server. If you do some searching around you can probably find some implementations that already exist. I don't have any specific recommendations.
-
kicken's post in Catching exceptions was marked as the answer
Because \CustomException does not exist. \Notion\RestApp\CustomException does.
-
kicken's post in Sockets and TLS was marked as the answer
One side needs the certificate + key (typically the server) and the other side needs just the certificate for verification purposes (typically the client).
The cafile option is part of PHP, not react. local_cert is as well.
SecureServer and SecureConnector call stream_context_set_option with whatever parameters you pass in the constructor so you won't find them within the react source anywhere, you need to look at the PHP documentation for the SSL wrapper.
If you add an error handler to your listening side you can get a more detailed message.
$server->on('error', function($error) use ($loop){ echo "Some error occured!\n"; var_dump($error); $loop->stop(); }); When I tried using similar code to what you posted, this is the error that was returned:
UnexpectedValueException: Unable to complete SSL/TLS handshake: stream_socket_enable_crypto(): Unable to set private key file `/home/kicken/secureTest/certificate.pem' in /home/kicken/secureTest/vendor/react/socket/src/StreamEncryption.php on line 117 There are two ways to resolve that error. Either combine your private key and certificate into a single file (just concatenate them together) or specify the location of the key file using the locak_pk option.
You may need to specify the proper name on the certificate for verification to complete successfully. You can do that using the peer_name option. I had to do that since I just used a random certificate I had laying around rather than create a new one explicitly for this purpose.
Server:
<?php require 'vendor/autoload.php'; $loop = \React\EventLoop\Factory::create(); $server = new \React\Socket\TcpServer('127.0.0.1:12123', $loop); $server = new \React\Socket\SecureServer($server, $loop, [ 'local_cert' => 'combined.pem' ]); $server->on('connection', function (\React\Socket\ConnectionInterface $conn) use($loop) { echo "Received new connection!\n"; var_dump($conn); $loop->stop(); }); $server->on('error', function($error) use ($loop){ echo "Some error occured!\n"; var_dump($error); $loop->stop(); }); $loop->run(); Client:
<?php require 'vendor/autoload.php'; $loop = \React\EventLoop\Factory::create(); $connector = new \React\Socket\TimeoutConnector(new \React\Socket\Connector($loop), 10, $loop); $connector = new \React\Socket\SecureConnector($connector, $loop, [ 'cafile' => 'certificate.pem' , 'peer_name' => 'Kickenscripts.us' ]); $connector->connect('127.0.0.1:12123') ->then(function (\React\Socket\ConnectionInterface $connection) use (&$response, $loop, $msg) { echo "Connected successfully!"; var_dump($connection); $loop->stop(); })->otherwise(function(\RuntimeException $error) use(&$response, $loop){ echo "Failed to connect!"; var_dump($error); $loop->stop(); }); $loop->run(); No, the extension doesn't make a difference. Some people use .crt to indicate a certificate, some use .pem because it's a PEM-encoded file format. Use whichever you prefer.
-
kicken's post in How to retrieve results from a stream? was marked as the answer
You should be using fread($fp, 4), not fgets.
fgets stops reading on new lines which might exist in your binary representation of your length. For example if your length were 266 that'd be encoded as 0A010000. 0A is the byte for a new line so fgets would stop reading there and return only 1 bytes rather than the 4 you requested.
Always use fread() if you want a specific number of bytes read. Only use fgets if you want the special "read until end of line" behavior. Also you always need to check the return value of your read to see how much was read. Even with blocking operations it's possible for a read to return less data than you requested.
-
kicken's post in Locking a file for passing data was marked as the answer
filesize
Your $filesize is only going to be correct the first time the function is called. After that you'll get the cached value back. Either clear the cache or read the file in a way that doesn't depend on obtaining the file size.
-
kicken's post in case when in where clause? was marked as the answer
No, but by binding your parameter multiple times you can add a second condition that is always true.
WHERE ci.id < ? AND (? IS NULL OR ci.cat_id = ?) $next24item->bind_param('iii', $lastItemID, $category_id, $category_id); If $category_id is null then the first condition ? IS NULL will always be true and cause the second condition to be ignored. If $category_id is not null then ? IS NULL will always be false and the second condition will be evaluated. -
kicken's post in Invalid numeric literal was marked as the answer
Numbers that begin with a 0 are octal based numbers. I'd guess you get the error due to running a 32-bit version of PHP, in which case 070000000000 is larger than PHP can handle as an integer.
On a related note, don't try and treat phone numbers as actual numbers, treat them a strings. Just because some value only consists of digits doesn't mean it needs to be treated as an integer type.
-
kicken's post in linux command sed was marked as the answer
The test.txt, file is not supposed to change, that's the backup in case you messed up. The original test.txt is the one that gets changed.
kicken@web1:~$ echo 'Visit www.example.com today!' > test.txt kicken@web1:~$ sed -i, s,www,the,g test.txt kicken@web1:~$ cat test.txt Visit the.example.com today! kicken@web1:~$ cat test.txt, Visit www.example.com today! kicken@web1:~$ -
kicken's post in Array[] or array() or wha? was marked as the answer
If you're just after the numerical value of the first byte, then you can simply do:
$byte = ord($buf[0]); echo $byte; Strings in PHP can be treated like an array and you can access the individual bytes directly by using the appropriate index. ord will give you the numeric value of a byte. There's no need for unpack at all in this code. If you want all the bytes you can do a for loop over the length of the string and run ord on each byte individually. -
kicken's post in "anonymous" array? was marked as the answer
array('A' => 5, 'B' => 4, 'C' => 3, 'D' => 2, 'E' => 1)[$overall]That works fine for PHP >=5.5.
Adding || 0 at the end would give you a boolean result, which I don't think is what you are intending. I'm guessing you want the javascript behavior where $pt_overall would be assigned either the value of the array or 0 if undefined. || does not work that way for PHP, you always get a boolean true or false instead.
If you want to lookup a value or default to 0, then you'll need to use as ternary statement, and you need to use isset() to avoid undefined index errors. You'll want to just assign your array to a variable in that case.
$values = ['A' => 5, 'B' => 4, 'C' => 3, 'D' => 2, 'E' => 1]; $pt_overall = isset($values[$overall])?$values[$overall]:0; -
kicken's post in Making Slim generate 404 response in application was marked as the answer
Use an exception and the error handler to return an appropriate error page.
$c['errorHandler'] = function($c){ return function ($request, $response, $exception) use ($c){ if ($exception instanceof NotFoundException){ return $c['notFoundHandler']($request, $response); } else { return $c['response']->withStatus(500) ->withHeader('Content-type: text/html') ->write('Generic error') ; } }; }; class SourceFactory { public function getByType($type, $subtype){ throw new NotFoundException(); } }
class NotFoundException extends Exception {} Whenever you want to trigger a not found error you'd just throw the exception. That will stop the current code path and jump to the error handler. The error handler will detect that it's a not found exception and call the not found handler to generate the response.
You could do the same with other http error conditions if you wanted, like authentication required, forbidden, etc. Symfony does something like this in their framework. They define a HTTPExceptionInterface adding methods to get the status code and extra headers. Then they have various implementations like NotFoundHttpException.
-
kicken's post in Send mail Raspberry Pi (sSMTP) was marked as the answer
Your reverse aliases file does not contain an entry for the www-data user which is what your script is running as. Try adding that and see if it works.
-
kicken's post in How to get content into a ReactPHP server? was marked as the answer
Your server and it's clients should communicate with some standard data layout. In my RLGL example for example every JSON structure contained a message field that indicated what type of data structure was being sent.
You can use that field to then decide what to do with any data you receive. One of those actions could be something to forward data to a given client which is what your index.php script would use.
$client->on('data', function($data) use ($client){ switch ($data['message']){ case 'register': $this->addConnection($client, $data['guid']); break; case 'forward': $forwardClient = $this->findConnectionByGuid($data['guid']); $forwardClient->send($data['data']); //Somehow determine success/failure and send the result //$client->send(['message'=> 'forward-result', 'success' => true]); break; default: $guid = $this->getConnectionID(); $this->app->process($data, $guid, $client); break; } }); Your index.php script can just use the react framework stuff to send your data and receive a response. Something like this:
function sendToClient($guid, $forwardData){ $success = false; $loop = new \React\EventLoop\StreamSelectLoop(); $socket = new \React\SocketClient\TimeoutConnector(new \React\SocketClient\TcpConnector($loop), 15, $loop); $socket->create($server, $port)->then(function($stream){ $client = new \Kicken\RLGL\JSONStream($stream); $stream->on('data', function($data) use (&$success, $loop, $stream, $guid, $forwardData){ if ($data['message'] == 'forward-result'){ $success = $data['success']; $stream->close(); $loop->stop(); } }); $client->send([ 'message' => 'forward' , 'guid' => $guid , 'data' => $forwardData ]); }); //Generic timeout so this function doesn't block forever. $loop->addTimer(30, function() use ($loop){ $loop->stop(); }); $loop->run(); return $success; }