How to sort Japanese like Excel - php
I want to sort Japanese words ( Kanji) like sort feature in excel.
I have tried many ways to sort Japanese text in PHP but the result is not 100% like result in excel.
First . I tried to convert Kanji to Katakana by using this lib (https://osdn.net/projects/igo-php/) but some case is not same like excel.
I want to sort these words ASC
けやきの家
高森台病院
みのりの里
My Result :
けやきの家
高森台病院
みのりの里
Excel Result:
けやきの家
みのりの里
高森台病院
Second I tried other way by using this function
mb_convert_kana($text, "KVc", "utf-8");
The sorting result is correct with those text above, but it contain some case not correct
米田病院
米田病院
高森台病院
My result :
米田病院
米田病院
高森台病院
Excel Result:
高森台病院
米田病院
米田病院
Do you guys have any idea about this. (Sorry for my English ) . Thank you
Firstly, Japanese kanji are not sortable. You can sort by its code number, but that order has no meanings.
Your using Igo (or any other morphological analysis libraries) sounds good solution, though it can not be perfect. And your first sort result seems fine for me. Why do you want them to be sorted in Excel order?
In Excel, if a cell keeps remembering its phonetic notations when the user initially typed on Japanese IME (Input Method Editor), that phonetics will be used in sort. That means, as not all cell might be typed manually on IME, some cells may not have information how those kanji-s are read. So results of sorting Kanji-s on Excel could be pretty unpredictable. (If sort seriously needed, usually we add another yomigana field, either in hiragana or katakana, and sort by that column.)
The second method mb_convert_kana() is totally off point. That function is to normalize hiragana/katakana, as there are two sets of letters by historical reason (full-width kana and half-width kana). Applying that function to your Japanese texts only changes kana parts. If that made your expectation satisfied, that must be coincidence.
You must define what Excel Japanese sort order your customer requires first. I will be happy to help you if it is clear.
[Update]
As op commented, mb_convert_kana() was to sort mixed hiragana/katakana. For that purpose, I suggest to use php_intl Collator. For example,
<?php
// demo: Japanese(kana) sort by php_intl Collator
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
exit ('php_intl extension is available on PHP 5.3.0 or later.');
}
if (!class_exists('Collator')) {
exit ('You need to install php_intl extension.');
}
$collator = new Collator('ja_JP');
$textArray = [
'カキクケコ',
'日本語',
'アアト',
'Alphabet',
'アイランド',
'はひふへほ',
'あいうえお',
'漢字',
'たほいや',
'さしみじょうゆ',
'Roma',
'ラリルレロ',
'アート',
];
$result = $collator->sort($textArray);
if ($result === false) {
echo "sort failed" . PHP_EOL;
exit();
}
var_dump($textArray);
This sorts hiragana/katakana mixed texts array. Results are here.
array(13) {
[0]=>
string(8) "Alphabet"
[1]=>
string(4) "Roma"
[2]=>
string(9) "アート"
[3]=>
string(9) "アアト"
[4]=>
string(15) "あいうえお"
[5]=>
string(15) "アイランド"
[6]=>
string(15) "カキクケコ"
[7]=>
string(21) "さしみじょうゆ"
[8]=>
string(12) "たほいや"
[9]=>
string(15) "はひふへほ"
[10]=>
string(15) "ラリルレロ"
[11]=>
string(6) "漢字"
[12]=>
string(9) "日本語"
}
You won't need to normalize them by yourself. Both PHP(though with php_intl extension) and database(such like MySQL) know how to sort alphabets in many languages so you do not need to write it.
And, this does not solve the original issue, Kanji sort.
Laravel Alpha to Hiragana with a custom function
Note : $modals (laravel models with get() )
alphabets : Hiragana orders
Source : https://gist.github.com/mdzhang/899a427eb3d0181cd762
public static function orderByHiranagana ($modals,$column){
$outArray = array();
$alphabets = array("a","i","u","e","o","ka","ki","ku","ke","ko","sa","shi","su","se","so","ta","chi","tsu","te","to","na","ni","nu","ne","no","ha","hi","fu","he","ho","ma","mi","mu","me","mo","ya","yu","yo","ra","ri","ru","re","ro","wa","wo","n","ga","gi","gu","ge","go","za","ji","zu","ze","zo","da","ji","zu","de","do","ba","bi","bu","be","bo","pa","pi","pu","pe","po","(pause)","kya","kyu","kyo","sha","shu","sho","cha","chu","cho","nya","nyu","nyo","hya","hyu","hyo","mya","myu","myo","rya","ryu","ryo","gya","gyu","gyo","ja","ju","jo","bya","byu","byo","pya","pyu","pyo","yi","ye","va","vi","vu","ve","vo","vya","vyu","vyo","she","je","che","swa","swi","swu","swe","swo","sya","syu","syo","si","zwa","zwi","zwu","zwe","zwo","zya","zyu","zyo","zi","tsa","tsi","tse","tso","tha","ti","thu","tye","tho","tya","tyu","tyo","dha","di","dhu","dye","dho","dya","dyu","dyo","twa","twi","tu","twe","two","dwa","dwi","du","dwe","dwo","fa","fi","hu","fe","fo","fya","fyu","fyo","ryi","rye","(wa)","wi","(wu)","we","wo","wya","wyu","wyo","kwa","kwi","kwu","kwe","kwo","gwa","gwi","gwu","gwe","gwe","mwa","mwi","mwu","mwe","mwo");
$existIds = array();
foreach ($alphabets as $alpha){
foreach ($modals as $modal) {
if($alpha == strtolower(substr($modal->$column, 0, strlen($alpha))) && !in_array($modal->id,$existIds)) {
array_push($outArray,$modal);
array_push($existIds,$modal->id);
}
}
}
return $outArray;
}
Call like this :
$students = Students::get();
$students = CommonHelper::orderByHiranagana($students,'lastname');
Related
Issue with accents and encoding with Bing Spell Check API v7
So I am trying to work with Bing's Spell Check API in PHP, but I'm having an issues where accents and other special characters aren't decoded properly, creating many errors that aren't in the original text and messing with the offsets. My implementation is quite simple - it's heavily based on the example they give in their documentation. I'm not sure if I am supposed to be doing something differently or if it is an issue on their side with how they decode those special characters (which seems highly unlikely - me messing something up is much more probable..!) Here's the code: $host = 'https://api.cognitive.microsoft.com'; $path = '/bing/v7.0/spellcheck?'; $data = array ( 'mkt' => $lang, 'mode' => 'proof', 'text' => urlencode($text) ); $encodedData = http_build_query($data); $key = 'subscription key redacted for obvious reasons'; $headers = "Content-type: application/x-www-form-urlencoded\r\n" . "Ocp-Apim-Subscription-Key: $key\r\n"; if (isset($_SERVER['REMOTE_ADDR'])) $headers .= "X-MSEdge-ClientIP: " . $_SERVER['REMOTE_ADDR'] . "\r\n"; $options = array ( 'http' => array ( 'header' => $headers, 'method' => 'POST', 'content' => $encodedData ) ); $context = stream_context_create ($options); $result = file_get_contents ($host . $path, false, $context); if ($result === FALSE) { # Handle error } $decodedResult = json_decode($result, true); If, for example, I try to spell check the following string: d'institution $encodedData becomes the following: mkt=fr-CA&method=proof&text=d%25E2%2580%2599institutions And the results I get from the API are the following: array(2) { ["_type"]=> string(10) "SpellCheck" ["flaggedTokens"]=> array(1) { [0]=> array(4) { ["offset"]=> int(8) ["token"]=> string(14) "99institutions" ["type"]=> string(12) "UnknownToken" ["suggestions"]=> array(2) { [0]=> array(2) { ["suggestion"]=> string(15) "99 institutions" ["score"]=> float(0.93191315174102) } [1]=> array(2) { ["suggestion"]=> string(14) "99 institution" ["score"]=> float(0.6518044080768) } } } } } As you can see, the decoding seems to be problematic, as the % gets encoded twice, and is only decoded once apparently. Now, if I remove the url_encode() when setting the value of 'text' in $data, it'll work fine for the apostrophe, but it doesn't work with accents. For example, the following string: Responsabilité is interpreted by the API as Responsabilité which returns an error. This could very well be something simple that I'm overlooking, but I've been struggling with this for quite a while and would appreciate any help I can get. Thanks, - Émile [ Edit ] Well, as always... when in doubt, assume you're wrong. The API recommended to change all of the accents for regular letters because even if the specified language was French, it still gave suggestions in English instead of returning an empty array. As for the accents that didn't seem to be decoded, well... I was var_dump-ing that data without any doctype set, so of course it would show without the proper encoding. Sorry about that - in the end, simply removing the urlencode() does the trick!
As per the docs: The API supports two proofing modes, Proof and Spell. The default mode is Proof. The Proof spelling mode provides the most comprehensive checks, but it's available only in the en-US (English-United States) market. For all other markets, set the mode query parameter to Spell. The Spell mode finds most spelling mistakes but doesn't find some of the grammar errors that Proof catches (for example, capitalization and repeated words).
PHP Mcrypt_decrypt decrypt only parts of the original string
I have a weird problem regarding passing an encrypted string through url. I'm using base64 encryptions from mcrypt() for encryptHTML() and decryptHTML(). I have this piece of code to encrypt: $link_string = http_build_query(array('index_number'=>30843854, 'extra_attendence_id'=>27982423, 'target_temporary_id'=>378492085, 'date'=>'2016-05-06', 'action'=>'OUT', 'target_id'=>390234), '', '&'); $link_string = encryptHTML($link_string); then I passed it through this url: 'localhost/website/controller/action/'.$link_string then I decrypted it with this piece of code: $id = $this->request->param('id'); $id = decryptHTML($id); parse_str($id, $arr_id2); var_dump($arr_id2); I will get these in return, as expected: array(6) { ["index_number"]=> string(8) "30843854" ["extra_attendence_id"]=> string(8) "27982423" ["target_temporary_id"]=> string(9) "378492085" ["date"]=> string(10) "2016-05-06" ["action"]=> string(3) "OUT" ["target_id"]=> string(6) "390234" } The next case is when I still want the encrypted link but I need to attach some other value from DOM element in the page, so I tried to 'localhost/website/controller/action/encrypt='.$link_string.'&DOMvalue=10000' then I modified the decryption with this piece of code: $id = $this->request->param('id'); parse_str($id, $arr_id2); $the_DOMValue = $arr_id2['DOMvalue']; $id = decryptHTML($arr_id2['crypted']); parse_str($id, $arr_id); var_dump($the_DOMValue); echo "<br>"; var_dump($arr_id); But then, I get these in return, to my surprise: string(5) "10000" array(3) { ["index_number"]=> string(13) "58_2016-04-26" ["extra_attendence_id"]=> string(1) "0" ["target_t"]=> string(0) "" } My original string was cut short! Note that the DOMvalue is fine. Then, I checked that right before both decryption, if the given encrypted string is different: on first case of decryptHTML: $id = $this->request->param('id'); var_dump($id); $id = decryptHTML($id); returns: string(224) "zCQnh-rNP2R7h4UHyV5Dm5zp494DIIku5LWN51yYGMXBaHf0gJgEDw8UCuHRZxr-CkjkevHQ70kOPnSBQ9CJP6lZrFone-nDMDJhYlL8330wz+zud8-3tSWvdOLB7je5D-22aX4OrE3zlBYZZZtI-rMT73H0JGIRzZge2GzcZGLwS7Rj+GL5Ym-ET6JEHDShST4etgcQaEYXml-+BZ2+0BQKvubZEBOB" on the second case of decryptHTML: $id = $this->request->param('id'); parse_str($id, $arr_id2); $the_DOMValue = $arr_id2['DOMvalue']; var_dump($arr_id2['crypted']); $id = decryptHTML($arr_id2['crypted']); returns: string(224) "zCQnh-rNP2R7h4UHyV5Dm5zp494DIIku5LWN51yYGMXBaHf0gJgEDw8UCuHRZxr-CkjkevHQ70kOPnSBQ9CJP6lZrFone-nDMDJhYlL8330wz zud8-3tSWvdOLB7je5D-22aX4OrE3zlBYZZZtI-rMT73H0JGIRzZge2GzcZGLwS7Rj GL5Ym-ET6JEHDShST4etgcQaEYXml- BZ2 0BQKvubZEBOB" It looks exactly the same to me, but strangely it was decrypted differently. I of course used the same functions to decrypt both cases... Anybody can shed me some light on this?
passing an encrypted string through url Passing an encrypted string through a URL is a bad idea. Full stop. I'm using base64 encryptions from mcrypt() for encryptHTML() and decryptHTML(). Without seeing what these functions do, this isn't helpful information, but mcrypt should be avoided. Use Libsodium (if you can; otherwise, use OpenSSL) instead. My original string was cut short! It probably treated the + as a space. Using urlencode() would fix one problem, but it wouldn't solve the vulnerability to chosen-ciphertext attacks that using mcrypt introduces into your application in the absence of a Message Authentication Code (MAC).
Getting a list of Contacts from Acumatica Web Services API using PHP
I'm trying to use the Acumatica Web Services API to get a list of Contacts (really I'm looking to get ANYTHING, but Contacts are what I'm playing with right now). I'm successfully able to get a SoapClient connected, but not sure what exactly to do from there to pull a list of all Contacts.
Seeing how you didn't specify Acumatica version or Webservices I'm assuming you are trying to use the "Screen WebAPI" that was in 5.2 and earlier and not the new "Contract Based API" in 5.3 With that in mind, here is an example of how to make the connection and retrieve a list of all of the contacts. The first step is to utilize the "acuwsdl2php" helper file to generate the needed screen helper classes for PHP. In the case of contacts: php acuwsdl2php.php {url of your site}/Soap/CR302000.asmx?WSDL CR302000 This will create the CR302000 subfolder with a Screen.php file that is the php equivalent of the schema for the screen. Second, here is a sample class that retrieves contact information <?php require_once('AcumaticaGate.php'); $client = new AcumaticaGate('{user}', '{password}', 'CR302000','{site}/Soap/'); $Contact_summary = $client->Schema->GetSchemaResult->ContactSummary; $Contact_detailsummary = $client->Schema->GetSchemaResult->DetailsSummary; $every_Contact = $Contact_summary->ServiceCommands->EveryContactID; $Contact = $Contact_summary->ContactID; $Contact_fname = $Contact_detailsummary->FirstName; $Contact_lname = $Contact_detailsummary->LastName; $export_param = new Export(); $export_param->commands = array($every_Contact, $Contact, $Contact_fname, $Contact_lname); $export_param->filters = array(); $export_param->breakOnError = false; $export_param->includeHeaders = true; $export_param->topCount = 0; $export = $client->Client->Export($export_param); print_r(var_dump($export)); The output here is something like this: [177]=> object(stdClass)#562 (1) { ["string"]=> array(3) { [0]=> string(3) "358" [1]=> string(4) "Anna" [2]=> string(7) "Johnson" } } [178]=> object(stdClass)#563 (1) { ["string"]=> array(3) { [0]=> string(3) "359" [1]=> string(4) "Yona" [2]=> string(5) "Jones" } } The acuwsdl2php and AcumaticaGate files are helper files that Acumatica provided to partners. They might also be available on the client portal for download. A quick google for them though and I believe you can find them on a few public sites. As a side note, these helper files were originally written for 4.x. You should look at the 5.x guides (assuming you have 5.x) for added information on logging off of a webapi when finished calling it.
Composer Package (PHPLeague) in Codeigniter loading class
I am aiming to use the following package for my project Color Extractor. I have composer working and setup in my project fine as per #philsturgeon's tutorial here, however I am stuck as the function returns an empty array for an image I know is there. I am autoloading in the index.php using require FCPATH.'vendor/autoload.php'; And I have tested this using Phil's example. My Code looks like this: $client = new League\ColorExtractor\Client(); $image = $client->loadJpeg(FCPATH.'assets/images/tumblr_ma7gmzwfAq1r780z3o1_250.jpg'); // Get the most used color hex code $palette = $image->extract(); // Get three most used color hex code $palette = $image->extract(3); // Change the Minimum Color Ratio (0 - 1) // Default: 0 $image->setMinColorRatio(1); $palette = $image->extract(); var_dump($palette); Can anyone tell me what I am doing wrong here as I don't have any errors in my log and I get the standard output. array(0) { }
I was being utterly stupid apologies for anyone who viewed this question I was trying to declare multiple variables with the same name and variants of the function. My final code looks like $client = new League\ColorExtractor\Client(); $image = $client->loadJpeg(FCPATH.'assets/images/tumblr_ma7gmzwfAq1r780z3o1_250.jpg'); $palette = $image->extract(3); var_dump($palette); Which returns an expected array like this. array(3) { [0]=> string(7) "#E09D73" [1]=> string(7) "#AC4C34" [2]=> string(7) "#EEDF6C" }
Cannot get the value of the xml fields
Hi i have this xml response that i parse and i can access the third text field, i have parsed it and i even do a var_dump($xmlObj->TerminalCommandResponse->Text); in which i get on screen object(SimpleXMLElement)#48 (14) { [0]=> string(4) "BB" [1]=> string(45) " *** BEST QUOTATION ***" [2]=> string(52) " FOR THIS ITI" [3]=> string(48) " *** BF SEGMENTS 1P/2P ***" ... } But when i try to directly access: $XMlText=$xmlObjFourth->TerminalCommandResponse->Text; var_dump($XMLText[2]); It doesn't show anything. I even tried a foreach loop in case i get the keys wrong but still the same issue <terminal:TerminalRsp xmlns:terminal="terminal_v50_0" TransactionId="F09006B80A0759BF61F85144F306F735" ResponseTime="527"> <terminal:TerminalCommandResponse> <terminal:Text>BB</terminal:Text> <terminal:Text>*** BEST QUOTATION ***</terminal:Text> <terminal:Text>FOR THIS ITI</terminal:Text> <terminal:Text>*** BF SEGMENTS 1P/2P ***</terminal:Text> <terminal:Text> PSGR PSG DES </terminal:Text> <terminal:Text>FQG 1 PY2PC 3640 6201 ADT </terminal:Text> <terminal:Text> GUARANTEED A </terminal:Text> <terminal:Text>)><</terminal:Text> </terminal:TerminalCommandResponse> </terminal:TerminalRsp>
Probably it is a special character or a whitespace that is blocking you, it is an interesting issue here what i think will help for starters foreach($XMLText as $k=>$tmp) { var_dump(preg_replace("/[^a-zA-Z0-9\s+]+/", "", $tmp)); } this way you can see whats in every field in the XMLText array